diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..8b35be4 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,15 @@ +# Copilot Instructions + +## Code Style +- When formatting C# code, wrap if statements onto two lines; do not use single-line if statements. + +## Project Guidelines +- When migrating or renaming code, reproduce existing tests for the new implementation to preserve test coverage; do not delete the old tests outright. +- For Auth0 and special SAML connection option mappings, keep controller/converter conversions manual; do not replace them with JSON-based mapping or add JSON converters to model classes because source and target models can be incompatible. Never use JsonConvertTo for Auth0-to-model transformations; every Auth0 type → model type conversion must be mapped by hand. Prefer explicit, manual representations or alternative mapping approaches instead of attaching JSON converters to the models. +- Extract nested conversion logic in controller mappings into separate FromApi/ToApi helper methods instead of inlining them inside larger conversion methods. + - Use explicit, manual mapping in these helpers for each nested type to preserve correctness and handle incompatibilities. + - When guarding assignments for manual converters, check the source property in the if-condition and keep the ToApi(...) call on the assignment's right-hand side; do not bind the converted or source value in the if pattern. + +### Generated Files / Code Generation +- Do not delete orphaned generated files when regenerating client V2alpha1 models unless explicitly requested. +- For client addon SharePoint external URLs, generate the V2alpha1 model property as string[] (always an array); do not use a union helper type for this field. \ No newline at end of file diff --git a/Alethic.Auth0.Operator.sln b/Alethic.Auth0.Operator.sln index 9d9d74f..d9b3648 100644 --- a/Alethic.Auth0.Operator.sln +++ b/Alethic.Auth0.Operator.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 18 -VisualStudioVersion = 18.1.11312.151 d18.0 +VisualStudioVersion = 18.1.11312.151 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E13F491D-01A4-4586-9D6C-C2B2150ACB65}" ProjectSection(SolutionItems) = preProject @@ -43,6 +43,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "targets", "targets", "{ABA7 EndProject Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "dist-images", "src\dist-images\dist-images.msbuildproj", "{4EB6F7F9-BEA2-EA96-955E-2ED53346803D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Alethic.Auth0.Operator.ModelGenerator", "src\Alethic.Auth0.Operator.ModelGenerator\Alethic.Auth0.Operator.ModelGenerator.csproj", "{881E837A-A326-BD1A-F0E0-0490CCA70CA8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -77,6 +79,10 @@ Global {4EB6F7F9-BEA2-EA96-955E-2ED53346803D}.Debug|Any CPU.Build.0 = Debug|Any CPU {4EB6F7F9-BEA2-EA96-955E-2ED53346803D}.Release|Any CPU.ActiveCfg = Release|Any CPU {4EB6F7F9-BEA2-EA96-955E-2ED53346803D}.Release|Any CPU.Build.0 = Release|Any CPU + {881E837A-A326-BD1A-F0E0-0490CCA70CA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {881E837A-A326-BD1A-F0E0-0490CCA70CA8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {881E837A-A326-BD1A-F0E0-0490CCA70CA8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {881E837A-A326-BD1A-F0E0-0490CCA70CA8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Alethic.Auth0.Operator.Core/Alethic.Auth0.Operator.Core.csproj b/src/Alethic.Auth0.Operator.Core/Alethic.Auth0.Operator.Core.csproj index 5aa5127..6ed4fbb 100644 --- a/src/Alethic.Auth0.Operator.Core/Alethic.Auth0.Operator.Core.csproj +++ b/src/Alethic.Auth0.Operator.Core/Alethic.Auth0.Operator.Core.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V1/V1ClientAddonSharePointExternalUrl.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V1/V1ClientAddonSharePointExternalUrl.cs index 92c3596..b6db0e8 100644 --- a/src/Alethic.Auth0.Operator.Core/Models/Client/V1/V1ClientAddonSharePointExternalUrl.cs +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V1/V1ClientAddonSharePointExternalUrl.cs @@ -13,13 +13,13 @@ public record V1ClientAddonSharePointExternalUrl /// [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Type { get; internal set; } + public string? Type { get; set; } /// /// Union value /// [JsonPropertyName("value")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public object? Value { get; internal set; } + public object? Value { get; set; } } \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V1/V1ClientComplianceLevel.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V1/V1ClientComplianceLevel.cs index 31cc26a..bef2803 100644 --- a/src/Alethic.Auth0.Operator.Core/Models/Client/V1/V1ClientComplianceLevel.cs +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V1/V1ClientComplianceLevel.cs @@ -8,13 +8,13 @@ public enum V1ClientComplianceLevel { [JsonStringEnumMemberName("none")] - NONE, + None, [JsonStringEnumMemberName("fapi1_adv_pkj_par")] - FAPI1_ADV_PKJ_PAR, + Fapi1AdvPkjPar, [JsonStringEnumMemberName("fapi1_adv_mtls_par")] - FAPI1_ADV_MTLS_PAR + Fapi1AdvMtlsPar } diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonAws.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonAws.cs new file mode 100644 index 0000000..1b57d13 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonAws.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonAws +{ + + [JsonPropertyName("principal")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Principal { get; set; } + + [JsonPropertyName("role")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Role { get; set; } + + [JsonPropertyName("lifetime_in_seconds")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? LifetimeInSeconds { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonAzureBlob.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonAzureBlob.cs new file mode 100644 index 0000000..72d4222 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonAzureBlob.cs @@ -0,0 +1,60 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonAzureBlob +{ + + [JsonPropertyName("accountName")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AccountName { get; set; } + + [JsonPropertyName("storageAccessKey")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? StorageAccessKey { get; set; } + + [JsonPropertyName("containerName")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ContainerName { get; set; } + + [JsonPropertyName("blobName")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? BlobName { get; set; } + + [JsonPropertyName("expiration")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Expiration { get; set; } + + [JsonPropertyName("signedIdentifier")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SignedIdentifier { get; set; } + + [JsonPropertyName("blob_read")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? BlobRead { get; set; } + + [JsonPropertyName("blob_write")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? BlobWrite { get; set; } + + [JsonPropertyName("blob_delete")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? BlobDelete { get; set; } + + [JsonPropertyName("container_read")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContainerRead { get; set; } + + [JsonPropertyName("container_write")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContainerWrite { get; set; } + + [JsonPropertyName("container_delete")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContainerDelete { get; set; } + + [JsonPropertyName("container_list")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContainerList { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonAzureSb.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonAzureSb.cs new file mode 100644 index 0000000..5231ce4 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonAzureSb.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonAzureSb +{ + + [JsonPropertyName("namespace")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Namespace { get; set; } + + [JsonPropertyName("sasKeyName")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SasKeyName { get; set; } + + [JsonPropertyName("sasKey")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SasKey { get; set; } + + [JsonPropertyName("entityPath")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? EntityPath { get; set; } + + [JsonPropertyName("expiration")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Expiration { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonEchoSign.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonEchoSign.cs new file mode 100644 index 0000000..8dbdceb --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonEchoSign.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonEchoSign +{ + + [JsonPropertyName("domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Domain { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonEgnyte.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonEgnyte.cs new file mode 100644 index 0000000..b659319 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonEgnyte.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonEgnyte +{ + + [JsonPropertyName("domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Domain { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonFirebase.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonFirebase.cs new file mode 100644 index 0000000..ac3bcd8 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonFirebase.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonFirebase +{ + + [JsonPropertyName("secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Secret { get; set; } + + [JsonPropertyName("private_key_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? PrivateKeyId { get; set; } + + [JsonPropertyName("private_key")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? PrivateKey { get; set; } + + [JsonPropertyName("client_email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientEmail { get; set; } + + [JsonPropertyName("lifetime_in_seconds")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? LifetimeInSeconds { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonLayer.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonLayer.cs new file mode 100644 index 0000000..973f508 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonLayer.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonLayer +{ + + [JsonPropertyName("providerId")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ProviderId { get; set; } + + [JsonPropertyName("keyId")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? KeyId { get; set; } + + [JsonPropertyName("privateKey")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? PrivateKey { get; set; } + + [JsonPropertyName("principal")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Principal { get; set; } + + [JsonPropertyName("expiration")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Expiration { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonMscrm.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonMscrm.cs new file mode 100644 index 0000000..f178a0f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonMscrm.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonMscrm +{ + + [JsonPropertyName("url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Url { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonNewRelic.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonNewRelic.cs new file mode 100644 index 0000000..8183438 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonNewRelic.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonNewRelic +{ + + [JsonPropertyName("account")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Account { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonOag.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonOag.cs new file mode 100644 index 0000000..12b08af --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonOag.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonOag +{ + + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonOffice365.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonOffice365.cs new file mode 100644 index 0000000..809feba --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonOffice365.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonOffice365 +{ + + [JsonPropertyName("domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Domain { get; set; } + + [JsonPropertyName("connection")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Connection { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonRms.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonRms.cs new file mode 100644 index 0000000..e6d57c4 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonRms.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonRms +{ + + [JsonPropertyName("url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Url { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSalesforce.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSalesforce.cs new file mode 100644 index 0000000..6e6d04b --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSalesforce.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSalesforce +{ + + [JsonPropertyName("entity_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? EntityId { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSalesforceApi.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSalesforceApi.cs new file mode 100644 index 0000000..0461757 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSalesforceApi.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSalesforceApi +{ + + [JsonPropertyName("clientid")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Clientid { get; set; } + + [JsonPropertyName("principal")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Principal { get; set; } + + [JsonPropertyName("communityName")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? CommunityName { get; set; } + + [JsonPropertyName("community_url_section")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? CommunityUrlSection { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSalesforceSandboxApi.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSalesforceSandboxApi.cs new file mode 100644 index 0000000..20b53a5 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSalesforceSandboxApi.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSalesforceSandboxApi +{ + + [JsonPropertyName("clientid")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Clientid { get; set; } + + [JsonPropertyName("principal")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Principal { get; set; } + + [JsonPropertyName("communityName")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? CommunityName { get; set; } + + [JsonPropertyName("community_url_section")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? CommunityUrlSection { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSaml.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSaml.cs new file mode 100644 index 0000000..8a038db --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSaml.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSaml +{ + + [JsonPropertyName("mappings")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? Mappings { get; set; } + + [JsonPropertyName("audience")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Audience { get; set; } + + [JsonPropertyName("recipient")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Recipient { get; set; } + + [JsonPropertyName("createUpnClaim")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? CreateUpnClaim { get; set; } + + [JsonPropertyName("mapUnknownClaimsAsIs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? MapUnknownClaimsAsIs { get; set; } + + [JsonPropertyName("passthroughClaimsWithNoMapping")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PassthroughClaimsWithNoMapping { get; set; } + + [JsonPropertyName("mapIdentities")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? MapIdentities { get; set; } + + [JsonPropertyName("signatureAlgorithm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SignatureAlgorithm { get; set; } + + [JsonPropertyName("digestAlgorithm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? DigestAlgorithm { get; set; } + + [JsonPropertyName("issuer")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Issuer { get; set; } + + [JsonPropertyName("destination")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Destination { get; set; } + + [JsonPropertyName("lifetimeInSeconds")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? LifetimeInSeconds { get; set; } + + [JsonPropertyName("signResponse")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SignResponse { get; set; } + + [JsonPropertyName("nameIdentifierFormat")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? NameIdentifierFormat { get; set; } + + [JsonPropertyName("nameIdentifierProbes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NameIdentifierProbes { get; set; } + + [JsonPropertyName("authnContextClassRef")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AuthnContextClassRef { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSapapi.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSapapi.cs new file mode 100644 index 0000000..5a9d168 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSapapi.cs @@ -0,0 +1,32 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSapapi +{ + + [JsonPropertyName("clientid")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Clientid { get; set; } + + [JsonPropertyName("usernameAttribute")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UsernameAttribute { get; set; } + + [JsonPropertyName("tokenEndpointUrl")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TokenEndpointUrl { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Scope { get; set; } + + [JsonPropertyName("servicePassword")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ServicePassword { get; set; } + + [JsonPropertyName("nameIdentifierFormat")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? NameIdentifierFormat { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSentry.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSentry.cs new file mode 100644 index 0000000..9748127 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSentry.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSentry +{ + + [JsonPropertyName("org_slug")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? OrgSlug { get; set; } + + [JsonPropertyName("base_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? BaseUrl { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSharePoint.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSharePoint.cs new file mode 100644 index 0000000..53e5b64 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSharePoint.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSharePoint +{ + + [JsonPropertyName("url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Url { get; set; } + + [JsonPropertyName("external_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? ExternalUrl { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSharePointExternalUrl.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSharePointExternalUrl.cs new file mode 100644 index 0000000..c950801 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSharePointExternalUrl.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSharePointExternalUrl +{ + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Type { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public object? Value { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSlack.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSlack.cs new file mode 100644 index 0000000..be25f9c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSlack.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSlack +{ + + [JsonPropertyName("team")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Team { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSpringCm.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSpringCm.cs new file mode 100644 index 0000000..0dcc0d4 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSpringCm.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSpringCm +{ + + [JsonPropertyName("acsurl")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Acsurl { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSsoIntegration.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSsoIntegration.cs new file mode 100644 index 0000000..5bad6d1 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonSsoIntegration.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonSsoIntegration +{ + + [JsonPropertyName("name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Name { get; set; } + + [JsonPropertyName("version")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Version { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonWams.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonWams.cs new file mode 100644 index 0000000..7860e93 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonWams.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonWams +{ + + [JsonPropertyName("masterkey")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Masterkey { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonZendesk.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonZendesk.cs new file mode 100644 index 0000000..921817d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonZendesk.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonZendesk +{ + + [JsonPropertyName("accountName")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AccountName { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonZoom.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonZoom.cs new file mode 100644 index 0000000..f9c30a4 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddonZoom.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddonZoom +{ + + [JsonPropertyName("account")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Account { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddons.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddons.cs new file mode 100644 index 0000000..098c6cb --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAddons.cs @@ -0,0 +1,129 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientAddons +{ + + [JsonPropertyName("aws")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonAws? Aws { get; set; } + + [JsonPropertyName("azure_blob")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonAzureBlob? AzureBlob { get; set; } + + [JsonPropertyName("azure_sb")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonAzureSb? AzureSb { get; set; } + + [JsonPropertyName("rms")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonRms? Rms { get; set; } + + [JsonPropertyName("mscrm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonMscrm? Mscrm { get; set; } + + [JsonPropertyName("slack")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonSlack? Slack { get; set; } + + [JsonPropertyName("sentry")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonSentry? Sentry { get; set; } + + [JsonPropertyName("box")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? Box { get; set; } + + [JsonPropertyName("cloudbees")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? Cloudbees { get; set; } + + [JsonPropertyName("concur")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? Concur { get; set; } + + [JsonPropertyName("dropbox")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? Dropbox { get; set; } + + [JsonPropertyName("echosign")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonEchoSign? Echosign { get; set; } + + [JsonPropertyName("egnyte")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonEgnyte? Egnyte { get; set; } + + [JsonPropertyName("firebase")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonFirebase? Firebase { get; set; } + + [JsonPropertyName("newrelic")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonNewRelic? Newrelic { get; set; } + + [JsonPropertyName("office365")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonOffice365? Office365 { get; set; } + + [JsonPropertyName("salesforce")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonSalesforce? Salesforce { get; set; } + + [JsonPropertyName("salesforce_api")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonSalesforceApi? SalesforceApi { get; set; } + + [JsonPropertyName("salesforce_sandbox_api")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonSalesforceSandboxApi? SalesforceSandboxApi { get; set; } + + [JsonPropertyName("samlp")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonSaml? Samlp { get; set; } + + [JsonPropertyName("layer")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonLayer? Layer { get; set; } + + [JsonPropertyName("sap_api")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonSapapi? SapApi { get; set; } + + [JsonPropertyName("sharepoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonSharePoint? Sharepoint { get; set; } + + [JsonPropertyName("springcm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonSpringCm? Springcm { get; set; } + + [JsonPropertyName("wams")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonWams? Wams { get; set; } + + [JsonPropertyName("wsfed")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? Wsfed { get; set; } + + [JsonPropertyName("zendesk")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonZendesk? Zendesk { get; set; } + + [JsonPropertyName("zoom")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonZoom? Zoom { get; set; } + + [JsonPropertyName("sso_integration")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonSsoIntegration? SsoIntegration { get; set; } + + [JsonPropertyName("oag")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddonOag? Oag { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAppTypeEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAppTypeEnum.cs new file mode 100644 index 0000000..6b5228e --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientAppTypeEnum.cs @@ -0,0 +1,84 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientAppTypeEnum +{ + + [JsonStringEnumMemberName("native")] + Native, + + [JsonStringEnumMemberName("spa")] + Spa, + + [JsonStringEnumMemberName("regular_web")] + RegularWeb, + + [JsonStringEnumMemberName("non_interactive")] + NonInteractive, + + [JsonStringEnumMemberName("resource_server")] + ResourceServer, + + [JsonStringEnumMemberName("express_configuration")] + ExpressConfiguration, + + [JsonStringEnumMemberName("rms")] + Rms, + + [JsonStringEnumMemberName("box")] + Box, + + [JsonStringEnumMemberName("cloudbees")] + Cloudbees, + + [JsonStringEnumMemberName("concur")] + Concur, + + [JsonStringEnumMemberName("dropbox")] + Dropbox, + + [JsonStringEnumMemberName("mscrm")] + Mscrm, + + [JsonStringEnumMemberName("echosign")] + Echosign, + + [JsonStringEnumMemberName("egnyte")] + Egnyte, + + [JsonStringEnumMemberName("newrelic")] + Newrelic, + + [JsonStringEnumMemberName("office365")] + Office365, + + [JsonStringEnumMemberName("salesforce")] + Salesforce, + + [JsonStringEnumMemberName("sentry")] + Sentry, + + [JsonStringEnumMemberName("sharepoint")] + Sharepoint, + + [JsonStringEnumMemberName("slack")] + Slack, + + [JsonStringEnumMemberName("springcm")] + Springcm, + + [JsonStringEnumMemberName("zendesk")] + Zendesk, + + [JsonStringEnumMemberName("zoom")] + Zoom, + + [JsonStringEnumMemberName("sso_integration")] + SsoIntegration, + + [JsonStringEnumMemberName("oag")] + Oag + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientComplianceLevelEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientComplianceLevelEnum.cs new file mode 100644 index 0000000..06f97d8 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientComplianceLevelEnum.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientComplianceLevelEnum +{ + + [JsonStringEnumMemberName("none")] + None, + + [JsonStringEnumMemberName("fapi1_adv_pkj_par")] + Fapi1AdvPkjPar, + + [JsonStringEnumMemberName("fapi1_adv_mtls_par")] + Fapi1AdvMtlsPar, + + [JsonStringEnumMemberName("fapi2_sp_pkj_mtls")] + Fapi2SpPkjMtls, + + [JsonStringEnumMemberName("fapi2_sp_mtls_mtls")] + Fapi2SpMtlsMtls + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientConf.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientConf.cs new file mode 100644 index 0000000..5f40f87 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientConf.cs @@ -0,0 +1,156 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1 +{ + + public record V2alpha1ClientConf + { + + [JsonPropertyName("signing_keys")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientSigningKey[]? SigningKeys { get; set; } + + [JsonPropertyName("app_type")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAppTypeEnum? ApplicationType { get; set; } + + [JsonPropertyName("token_endpoint_auth_method")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientTokenEndpointAuthMethodEnum? TokenEndpointAuthMethod { get; set; } + + [JsonPropertyName("addons")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientAddons? AddOns { get; set; } + + [JsonPropertyName("allowed_clients")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? AllowedClients { get; set; } + + [JsonPropertyName("allowed_logout_urls")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? AllowedLogoutUrls { get; set; } + + [JsonPropertyName("allowed_origins")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? AllowedOrigins { get; set; } + + [JsonPropertyName("web_origins")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? WebOrigins { get; set; } + + [JsonPropertyName("initiate_login_uri")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? InitiateLoginUri { get; set; } + + [JsonPropertyName("callbacks")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Callbacks { get; set; } + + [JsonPropertyName("client_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? ClientAliases { get; set; } + + [JsonPropertyName("client_metadata")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? ClientMetaData { get; set; } + + [JsonPropertyName("custom_login_page_on")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? IsCustomLoginPageOn { get; set; } + + [JsonPropertyName("is_first_party")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? IsFirstParty { get; set; } + + [JsonPropertyName("custom_login_page")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? CustomLoginPage { get; set; } + + [JsonPropertyName("custom_login_page_preview")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? CustomLoginPagePreview { get; set; } + + [JsonPropertyName("encryption_key")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientEncryptionKey? EncryptionKey { get; set; } + + [JsonPropertyName("form_template")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? FormTemplate { get; set; } + + [JsonPropertyName("grant_types")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? GrantTypes { get; set; } + + [JsonPropertyName("jwt_configuration")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientJwtConfiguration? JwtConfiguration { get; set; } + + [JsonPropertyName("mobile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientMobile? Mobile { get; set; } + + [JsonPropertyName("name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Name { get; set; } + + [JsonPropertyName("description")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Description { get; set; } + + [JsonPropertyName("logo_uri")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? LogoUri { get; set; } + + [JsonPropertyName("oidc_conformant")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? OidcConformant { get; set; } + + [JsonPropertyName("oidc_logout")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientOidcBackchannelLogoutSettings? OidcLogout { get; set; } + + [JsonPropertyName("resource_servers")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V1ClientReference[]? ResourceServers { get; set; } + + [JsonPropertyName("sso")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Sso { get; set; } + + [JsonPropertyName("refresh_token")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientRefreshTokenConfiguration? RefreshToken { get; set; } + + [JsonPropertyName("organization_usage")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientOrganizationUsageEnum? OrganizationUsage { get; set; } + + [JsonPropertyName("organization_require_behavior")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientOrganizationRequireBehaviorEnum? OrganizationRequireBehavior { get; set; } + + [JsonPropertyName("cross_origin_authentication")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? CrossOriginAuthentication { get; set; } + + [JsonPropertyName("require_pushed_authorization_requests")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RequirePushedAuthorizationRequests { get; set; } + + [JsonPropertyName("default_organization")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientDefaultOrganization? DefaultOrganization { get; set; } + + [JsonPropertyName("compliance_level")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientComplianceLevelEnum? ComplianceLevel { get; set; } + + [JsonPropertyName("require_proof_of_possession")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RequireProofOfPossession { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientDefaultOrganization.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientDefaultOrganization.cs new file mode 100644 index 0000000..30a843c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientDefaultOrganization.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientDefaultOrganization +{ + + [JsonPropertyName("organization_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? OrganizationId { get; set; } + + [JsonPropertyName("flows")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientDefaultOrganizationFlowsEnum[]? Flows { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientDefaultOrganizationFlowsEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientDefaultOrganizationFlowsEnum.cs new file mode 100644 index 0000000..bc02bdf --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientDefaultOrganizationFlowsEnum.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientDefaultOrganizationFlowsEnum +{ + + [JsonStringEnumMemberName("client_credentials")] + ClientCredentials + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientEncryptionKey.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientEncryptionKey.cs new file mode 100644 index 0000000..a41bba7 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientEncryptionKey.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientEncryptionKey +{ + + [JsonPropertyName("pub")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Pub { get; set; } + + [JsonPropertyName("cert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Cert { get; set; } + + [JsonPropertyName("subject")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Subject { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientFind.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientFind.cs new file mode 100644 index 0000000..df979c3 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientFind.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1 +{ + + public record V2alpha1ClientFind + { + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Name { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientJwtConfiguration.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientJwtConfiguration.cs new file mode 100644 index 0000000..1b08b45 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientJwtConfiguration.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientJwtConfiguration +{ + + [JsonPropertyName("lifetime_in_seconds")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? LifetimeInSeconds { get; set; } + + [JsonPropertyName("secret_encoded")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SecretEncoded { get; set; } + + [JsonPropertyName("scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? Scopes { get; set; } + + [JsonPropertyName("alg")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientSigningAlgorithmEnum? Alg { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientMobile.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientMobile.cs new file mode 100644 index 0000000..50efc87 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientMobile.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientMobile +{ + + [JsonPropertyName("android")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientMobileAndroid? Android { get; set; } + + [JsonPropertyName("ios")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientMobileiOs? Ios { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientMobileAndroid.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientMobileAndroid.cs new file mode 100644 index 0000000..1b2677f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientMobileAndroid.cs @@ -0,0 +1,17 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientMobileAndroid +{ + + [JsonPropertyName("app_package_name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AppPackageName { get; set; } + + [JsonPropertyName("sha256_cert_fingerprints")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Sha256CertFingerprints { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientMobileiOs.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientMobileiOs.cs new file mode 100644 index 0000000..56c6353 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientMobileiOs.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientMobileiOs +{ + + [JsonPropertyName("team_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TeamId { get; set; } + + [JsonPropertyName("app_bundle_identifier")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AppBundleIdentifier { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutInitiators.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutInitiators.cs new file mode 100644 index 0000000..dfc9eb2 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutInitiators.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientOidcBackchannelLogoutInitiators +{ + + [JsonPropertyName("mode")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum? Mode { get; set; } + + [JsonPropertyName("selected_initiators")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum[]? SelectedInitiators { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.cs new file mode 100644 index 0000000..8b016bb --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.cs @@ -0,0 +1,36 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum +{ + + [JsonStringEnumMemberName("rp_logout")] + RpLogout, + + [JsonStringEnumMemberName("idp_logout")] + IdpLogout, + + [JsonStringEnumMemberName("password_changed")] + PasswordChanged, + + [JsonStringEnumMemberName("session_expired")] + SessionExpired, + + [JsonStringEnumMemberName("session_revoked")] + SessionRevoked, + + [JsonStringEnumMemberName("account_deleted")] + AccountDeleted, + + [JsonStringEnumMemberName("email_identifier_changed")] + EmailIdentifierChanged, + + [JsonStringEnumMemberName("mfa_phone_unenrolled")] + MfaPhoneUnenrolled, + + [JsonStringEnumMemberName("account_deactivated")] + AccountDeactivated + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.cs new file mode 100644 index 0000000..786c6ee --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum +{ + + [JsonStringEnumMemberName("custom")] + Custom, + + [JsonStringEnumMemberName("all")] + All + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutSessionMetadata.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutSessionMetadata.cs new file mode 100644 index 0000000..c8736f2 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutSessionMetadata.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientOidcBackchannelLogoutSessionMetadata +{ + + [JsonPropertyName("include")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Include { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutSettings.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutSettings.cs new file mode 100644 index 0000000..461dce9 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOidcBackchannelLogoutSettings.cs @@ -0,0 +1,21 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientOidcBackchannelLogoutSettings +{ + + [JsonPropertyName("backchannel_logout_urls")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? BackchannelLogoutUrls { get; set; } + + [JsonPropertyName("backchannel_logout_initiators")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientOidcBackchannelLogoutInitiators? BackchannelLogoutInitiators { get; set; } + + [JsonPropertyName("backchannel_logout_session_metadata")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientOidcBackchannelLogoutSessionMetadata? BackchannelLogoutSessionMetadata { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOrganizationRequireBehaviorEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOrganizationRequireBehaviorEnum.cs new file mode 100644 index 0000000..e3a9527 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOrganizationRequireBehaviorEnum.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientOrganizationRequireBehaviorEnum +{ + + [JsonStringEnumMemberName("no_prompt")] + NoPrompt, + + [JsonStringEnumMemberName("pre_login_prompt")] + PreLoginPrompt, + + [JsonStringEnumMemberName("post_login_prompt")] + PostLoginPrompt + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOrganizationUsageEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOrganizationUsageEnum.cs new file mode 100644 index 0000000..8cf6c4d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientOrganizationUsageEnum.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientOrganizationUsageEnum +{ + + [JsonStringEnumMemberName("deny")] + Deny, + + [JsonStringEnumMemberName("allow")] + Allow, + + [JsonStringEnumMemberName("require")] + Require + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenConfiguration.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenConfiguration.cs new file mode 100644 index 0000000..67ba951 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenConfiguration.cs @@ -0,0 +1,40 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientRefreshTokenConfiguration +{ + + [JsonPropertyName("rotation_type")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientRefreshTokenRotationTypeEnum? RotationType { get; set; } + + [JsonPropertyName("expiration_type")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientRefreshTokenExpirationTypeEnum? ExpirationType { get; set; } + + [JsonPropertyName("leeway")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Leeway { get; set; } + + [JsonPropertyName("token_lifetime")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? TokenLifetime { get; set; } + + [JsonPropertyName("infinite_token_lifetime")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? InfiniteTokenLifetime { get; set; } + + [JsonPropertyName("idle_token_lifetime")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? IdleTokenLifetime { get; set; } + + [JsonPropertyName("infinite_idle_token_lifetime")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? InfiniteIdleTokenLifetime { get; set; } + + [JsonPropertyName("policies")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ClientRefreshTokenPolicy[]? Policies { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenExpirationTypeEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenExpirationTypeEnum.cs new file mode 100644 index 0000000..f4c629c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenExpirationTypeEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientRefreshTokenExpirationTypeEnum +{ + + [JsonStringEnumMemberName("expiring")] + Expiring, + + [JsonStringEnumMemberName("non_expiring")] + NonExpiring + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenPolicy.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenPolicy.cs new file mode 100644 index 0000000..58c724d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenPolicy.cs @@ -0,0 +1,17 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientRefreshTokenPolicy +{ + + [JsonPropertyName("audience")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Audience { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenRotationTypeEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenRotationTypeEnum.cs new file mode 100644 index 0000000..dbdb68c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientRefreshTokenRotationTypeEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientRefreshTokenRotationTypeEnum +{ + + [JsonStringEnumMemberName("rotating")] + Rotating, + + [JsonStringEnumMemberName("non_rotating")] + NonRotating + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientSigningAlgorithmEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientSigningAlgorithmEnum.cs new file mode 100644 index 0000000..94fdda0 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientSigningAlgorithmEnum.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientSigningAlgorithmEnum +{ + + [JsonStringEnumMemberName("hs256")] + Hs256, + + [JsonStringEnumMemberName("rs256")] + Rs256, + + [JsonStringEnumMemberName("rs512")] + Rs512, + + [JsonStringEnumMemberName("ps256")] + Ps256 + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientSigningKey.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientSigningKey.cs new file mode 100644 index 0000000..c7d1a3e --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientSigningKey.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +public record V2alpha1ClientSigningKey +{ + + [JsonPropertyName("pkcs7")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Pkcs7 { get; set; } + + [JsonPropertyName("cert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Cert { get; set; } + + [JsonPropertyName("subject")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Subject { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientTokenEndpointAuthMethodEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientTokenEndpointAuthMethodEnum.cs new file mode 100644 index 0000000..260d3cf --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Client/V2alpha1/V2alpha1ClientTokenEndpointAuthMethodEnum.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ClientTokenEndpointAuthMethodEnum +{ + + [JsonStringEnumMemberName("none")] + None, + + [JsonStringEnumMemberName("client_secret_post")] + ClientSecretPost, + + [JsonStringEnumMemberName("client_secret_basic")] + ClientSecretBasic + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionApiBehaviorEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionApiBehaviorEnum.cs new file mode 100644 index 0000000..2ac643d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionApiBehaviorEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionApiBehaviorEnum +{ + + [JsonStringEnumMemberName("required")] + Required, + + [JsonStringEnumMemberName("optional")] + Optional + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAssertionDecryptionAlgorithmProfile.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAssertionDecryptionAlgorithmProfile.cs new file mode 100644 index 0000000..69ac317 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAssertionDecryptionAlgorithmProfile.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Algorithm profile used to decrypt incoming SAML assertion content. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionAssertionDecryptionAlgorithmProfile + { + + /// The v2026-1 algorithm profile. + [JsonStringEnumMemberName("v2026-1")] + V20261, + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAssertionDecryptionAlgorithmProfileEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAssertionDecryptionAlgorithmProfileEnum.cs new file mode 100644 index 0000000..5bc18f9 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAssertionDecryptionAlgorithmProfileEnum.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionAssertionDecryptionAlgorithmProfileEnum +{ + + [JsonStringEnumMemberName("v20261")] + V20261 + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAssertionDecryptionSettings.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAssertionDecryptionSettings.cs new file mode 100644 index 0000000..74f34da --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAssertionDecryptionSettings.cs @@ -0,0 +1,17 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionAssertionDecryptionSettings +{ + + [JsonPropertyName("algorithm_profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAssertionDecryptionAlgorithmProfileEnum? AlgorithmProfile { get; set; } + + [JsonPropertyName("algorithm_exceptions")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? AlgorithmExceptions { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributeIdentifier.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributeIdentifier.cs new file mode 100644 index 0000000..a91230a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributeIdentifier.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionAttributeIdentifier +{ + + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + + [JsonPropertyName("default_method")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDefaultMethodEmailIdentifierEnum? DefaultMethod { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributeMapOidc.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributeMapOidc.cs new file mode 100644 index 0000000..506e16c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributeMapOidc.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionAttributeMapOidc +{ + + [JsonPropertyName("attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? Attributes { get; set; } + + [JsonPropertyName("mapping_mode")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionMappingModeEnumOidc? MappingMode { get; set; } + + [JsonPropertyName("userinfo_scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UserinfoScope { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributeMapOkta.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributeMapOkta.cs new file mode 100644 index 0000000..fa4f27b --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributeMapOkta.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionAttributeMapOkta +{ + + [JsonPropertyName("attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? Attributes { get; set; } + + [JsonPropertyName("mapping_mode")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionMappingModeEnumOkta? MappingMode { get; set; } + + [JsonPropertyName("userinfo_scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UserinfoScope { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributes.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributes.cs new file mode 100644 index 0000000..e27af62 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAttributes.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionAttributes +{ + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionEmailAttribute? Email { get; set; } + + [JsonPropertyName("phone_number")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPhoneAttribute? PhoneNumber { get; set; } + + [JsonPropertyName("username")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionUsernameAttribute? Username { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAuthenticationMethods.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAuthenticationMethods.cs new file mode 100644 index 0000000..4a44f47 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionAuthenticationMethods.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionAuthenticationMethods +{ + + [JsonPropertyName("password")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordAuthenticationMethod? Password { get; set; } + + [JsonPropertyName("passkey")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasskeyAuthenticationMethod? Passkey { get; set; } + + [JsonPropertyName("email_otp")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionEmailOtpAuthenticationMethod? EmailOtp { get; set; } + + [JsonPropertyName("phone_otp")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPhoneOtpAuthenticationMethod? PhoneOtp { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionChallengeUi.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionChallengeUi.cs new file mode 100644 index 0000000..8a22228 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionChallengeUi.cs @@ -0,0 +1,27 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Specifies how the passkey challenge is presented to the user in the Universal Login experience. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionChallengeUi + { + + /// Both autofill and button challenge UI options are shown. + [JsonStringEnumMemberName("both")] + Both, + + /// Only the browser autofill (conditional mediation) UI is shown. + [JsonStringEnumMemberName("autofill")] + AutoFill, + + /// Only the explicit passkey button UI is shown. + [JsonStringEnumMemberName("button")] + Button + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionConf.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionConf.cs new file mode 100644 index 0000000..ee34be0 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionConf.cs @@ -0,0 +1,88 @@ +using System.Collections; +using System.Text.Json.Serialization; + +using Alethic.Auth0.Operator.Core.Extensions; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Desired configuration for an Auth0 connection resource. + /// + public record V2alpha1ConnectionConf + { + + /// + /// The name of the connection. Must be unique for the tenant. Max length 35 characters and must start and end with an alphanumeric character and can only contain alphanumeric characters and '-'. + /// + [JsonPropertyName("name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Name { get; set; } + + /// + /// The display name of the connection, shown to end users in the Universal Login experience. + /// + [JsonPropertyName("display_name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? DisplayName { get; set; } + + /// + /// The identity provider identifier. Determines which strategy-specific options object is used. + /// + [JsonPropertyName("strategy")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionStrategy? Strategy { get; set; } + + /// + /// Provisioning ticket URL used for enterprise connections during setup. + /// + [JsonPropertyName("provisioning_ticket_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ProvisioningTicketUrl { get; set; } + + /// + /// Metadata associated with the connection in the form of an object with string values (max 255 chars). A maximum of 10 metadata properties are allowed. + /// + [JsonPropertyName("metadata")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonConverter(typeof(SimplePrimitiveHashtableConverter))] + public Hashtable? Metadata { get; set; } + + /// + /// Defines the realms for which the connection will be used (e.g. email domains). If not specified, the connection name will be added as realm. + /// + [JsonPropertyName("realms")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Realms { get; set; } + + /// + /// The list of clients for which the connection is enabled. + /// + [JsonPropertyName("enabled_clients")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V1ClientReference[]? EnabledClients { get; set; } + + /// + /// Whether the connection is shown as a button. Only for enterprise connections. + /// + [JsonPropertyName("show_as_button")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ShowAsButton { get; set; } + + /// + /// True if the connection is a domain level connection, false otherwise. + /// + [JsonPropertyName("is_domain_connection")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? IsDomainConnection { get; set; } = false; + + /// + /// A typed union of options. + /// + [JsonPropertyName("options")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptions? Options { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionConnectionSettings.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionConnectionSettings.cs new file mode 100644 index 0000000..7889bea --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionConnectionSettings.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionConnectionSettings +{ + + [JsonPropertyName("pkce")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionConnectionSettingsPkceEnum? Pkce { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionConnectionSettingsPkceEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionConnectionSettingsPkceEnum.cs new file mode 100644 index 0000000..a3cfe51 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionConnectionSettingsPkceEnum.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionConnectionSettingsPkceEnum +{ + + [JsonStringEnumMemberName("auto")] + Auto, + + [JsonStringEnumMemberName("s256")] + S256, + + [JsonStringEnumMemberName("plain")] + Plain, + + [JsonStringEnumMemberName("disabled")] + Disabled + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionCustomScripts.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionCustomScripts.cs new file mode 100644 index 0000000..f25edd9 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionCustomScripts.cs @@ -0,0 +1,44 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionCustomScripts +{ + + [JsonPropertyName("login")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Login { get; set; } + + [JsonPropertyName("get_user")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? GetUser { get; set; } + + [JsonPropertyName("delete")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Delete { get; set; } + + [JsonPropertyName("change_password")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ChangePassword { get; set; } + + [JsonPropertyName("verify")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Verify { get; set; } + + [JsonPropertyName("create")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Create { get; set; } + + [JsonPropertyName("change_username")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ChangeUsername { get; set; } + + [JsonPropertyName("change_email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ChangeEmail { get; set; } + + [JsonPropertyName("change_phone_number")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ChangePhoneNumber { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDecryptionKeySaml.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDecryptionKeySaml.cs new file mode 100644 index 0000000..43cb59d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDecryptionKeySaml.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionDecryptionKeySaml +{ + + [JsonPropertyName("privateKey")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? PrivateKey { get; set; } + + [JsonPropertyName("keyPair")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDecryptionKeySamlCert? KeyPair { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDecryptionKeySamlCert.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDecryptionKeySamlCert.cs new file mode 100644 index 0000000..03d960f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDecryptionKeySamlCert.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionDecryptionKeySamlCert +{ + + [JsonPropertyName("cert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Cert { get; set; } + + [JsonPropertyName("key")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Key { get; set; } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDefaultMethodEmailIdentifierEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDefaultMethodEmailIdentifierEnum.cs new file mode 100644 index 0000000..8fc43f7 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDefaultMethodEmailIdentifierEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionDefaultMethodEmailIdentifierEnum +{ + + [JsonStringEnumMemberName("password")] + Password, + + [JsonStringEnumMemberName("email_otp")] + EmailOtp + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDigestAlgorithmEnumSaml.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDigestAlgorithmEnumSaml.cs new file mode 100644 index 0000000..9ac0ceb --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDigestAlgorithmEnumSaml.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionDigestAlgorithmEnumSaml +{ + + [JsonStringEnumMemberName("sha1")] + Sha1, + + [JsonStringEnumMemberName("sha256")] + Sha256 + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDpopSigningAlgEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDpopSigningAlgEnum.cs new file mode 100644 index 0000000..38b7610 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionDpopSigningAlgEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionDpopSigningAlgEnum +{ + + [JsonStringEnumMemberName("es256")] + Es256, + + [JsonStringEnumMemberName("ed25519")] + Ed25519 + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailAttribute.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailAttribute.cs new file mode 100644 index 0000000..954c685 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailAttribute.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionEmailAttribute +{ + + [JsonPropertyName("identifier")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAttributeIdentifier? Identifier { get; set; } + + [JsonPropertyName("unique")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Unique { get; set; } + + [JsonPropertyName("profile_required")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ProfileRequired { get; set; } + + [JsonPropertyName("verification_method")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionVerificationMethodEnum? VerificationMethod { get; set; } + + [JsonPropertyName("signup")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignupVerified? Signup { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailEmail.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailEmail.cs new file mode 100644 index 0000000..1e97678 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailEmail.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionEmailEmail +{ + + [JsonPropertyName("body")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Body { get; set; } + + [JsonPropertyName("from")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? From { get; set; } + + [JsonPropertyName("subject")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Subject { get; set; } + + [JsonPropertyName("syntax")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionEmailEmailSyntax? Syntax { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailEmailSyntax.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailEmailSyntax.cs new file mode 100644 index 0000000..5548d75 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailEmailSyntax.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionEmailEmailSyntax +{ + + [JsonStringEnumMemberName("liquid")] + Liquid + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailMessage.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailMessage.cs new file mode 100644 index 0000000..249bc2a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailMessage.cs @@ -0,0 +1,41 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + /// + /// Email message template configuration (subject, body, from address, and syntax). + /// + public record V2alpha1ConnectionEmailMessage + { + + /// + /// The sender address for the magic-link email. + /// + [JsonPropertyName("from")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? From { get; set; } + + /// + /// Subject line of the magic-link email. + /// + [JsonPropertyName("subject")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Subject { get; set; } + + /// + /// Body of the magic-link email (may contain Liquid template syntax). + /// + [JsonPropertyName("body")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Body { get; set; } + + /// + /// Template syntax used in the body. Use "liquid" for Liquid templates. + /// + [JsonPropertyName("syntax")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Syntax { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailOtpAuthenticationMethod.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailOtpAuthenticationMethod.cs new file mode 100644 index 0000000..ec01054 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailOtpAuthenticationMethod.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionEmailOtpAuthenticationMethod +{ + + [JsonPropertyName("enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enabled { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailTotp.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailTotp.cs new file mode 100644 index 0000000..c6b42db --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionEmailTotp.cs @@ -0,0 +1,27 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + /// + /// TOTP (time-based one-time password) configuration for the email connection. + /// + public record V2alpha1ConnectionEmailTotp + { + + /// + /// Length of the one-time password. + /// + [JsonPropertyName("length")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Length { get; set; } + + /// + /// Time step in seconds for TOTP code generation. + /// + [JsonPropertyName("time_step")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? TimeStep { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionFederatedConnectionsAccessTokens.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionFederatedConnectionsAccessTokens.cs new file mode 100644 index 0000000..3c41cbf --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionFederatedConnectionsAccessTokens.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionFederatedConnectionsAccessTokens +{ + + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionFind.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionFind.cs new file mode 100644 index 0000000..e92424c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionFind.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Lookup criteria used to locate an existing Auth0 connection resource. + /// + public record V2alpha1ConnectionFind + { + + /// + /// The ID of the connection to find. + /// + [JsonPropertyName("id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ConnectionId { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionGatewayAuthentication.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionGatewayAuthentication.cs new file mode 100644 index 0000000..d05e033 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionGatewayAuthentication.cs @@ -0,0 +1,48 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Authentication settings used when Auth0 calls a custom SMS or email gateway. + /// + public record V2alpha1ConnectionGatewayAuthentication + { + + /// + /// Authentication method to use when calling the gateway. Can be bearer or query. + /// + [JsonPropertyName("method")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Method { get; set; } + + /// + /// Subject claim for JWT bearer tokens sent to the gateway. + /// + [JsonPropertyName("subject")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Subject { get; set; } + + /// + /// Audience claim for JWT bearer tokens sent to the gateway. + /// + [JsonPropertyName("audience")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Audience { get; set; } + + /// + /// Shared secret used to sign JWT bearer tokens sent to the gateway. + /// + [JsonPropertyName("secret")] + public string? Secret { get; set; } + + /// + /// When true, the shared secret is Base64-encoded. + /// + [JsonPropertyName("secret_base64_encoded")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SecretBase64Encoded { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionGatewayAuthenticationSms.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionGatewayAuthenticationSms.cs new file mode 100644 index 0000000..6ecc943 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionGatewayAuthenticationSms.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionGatewayAuthenticationSms +{ + + [JsonPropertyName("audience")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Audience { get; set; } + + [JsonPropertyName("method")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Method { get; set; } + + [JsonPropertyName("secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Secret { get; set; } + + [JsonPropertyName("secret_base64_encoded")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SecretBase64Encoded { get; set; } + + [JsonPropertyName("subject")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Subject { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionGoogleAppsFederatedConnectionsAccessTokens.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionGoogleAppsFederatedConnectionsAccessTokens.cs new file mode 100644 index 0000000..38f7ba4 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionGoogleAppsFederatedConnectionsAccessTokens.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + public record V2alpha1ConnectionGoogleAppsFederatedConnectionsAccessTokens + { + + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdTokenSignedResponseAlgEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdTokenSignedResponseAlgEnum.cs new file mode 100644 index 0000000..e71a975 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdTokenSignedResponseAlgEnum.cs @@ -0,0 +1,30 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionIdTokenSignedResponseAlgEnum +{ + + [JsonStringEnumMemberName("es256")] + Es256, + + [JsonStringEnumMemberName("es384")] + Es384, + + [JsonStringEnumMemberName("ps256")] + Ps256, + + [JsonStringEnumMemberName("ps384")] + Ps384, + + [JsonStringEnumMemberName("rs256")] + Rs256, + + [JsonStringEnumMemberName("rs384")] + Rs384, + + [JsonStringEnumMemberName("rs512")] + Rs512 + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdentifierPrecedence.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdentifierPrecedence.cs new file mode 100644 index 0000000..91cdd0b --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdentifierPrecedence.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionIdentifierPrecedence + { + + [JsonStringEnumMemberName("email")] + Email, + + [JsonStringEnumMemberName("phone_number")] + PhoneNumber, + + [JsonStringEnumMemberName("username")] + Username, + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdentifierPrecedenceEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdentifierPrecedenceEnum.cs new file mode 100644 index 0000000..a3f816b --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdentifierPrecedenceEnum.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionIdentifierPrecedenceEnum +{ + + [JsonStringEnumMemberName("email")] + Email, + + [JsonStringEnumMemberName("phone_number")] + PhoneNumber, + + [JsonStringEnumMemberName("username")] + Username + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdentityApiEnumAzureAd.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdentityApiEnumAzureAd.cs new file mode 100644 index 0000000..8197494 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdentityApiEnumAzureAd.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionIdentityApiEnumAzureAd +{ + + [JsonStringEnumMemberName("microsoft_identity_platform_v20")] + MicrosoftIdentityPlatformV20, + + [JsonStringEnumMemberName("azure_active_directory_v10")] + AzureActiveDirectoryV10 + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdpInitiatedClientProtocol.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdpInitiatedClientProtocol.cs new file mode 100644 index 0000000..43c0e2c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionIdpInitiatedClientProtocol.cs @@ -0,0 +1,27 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Protocol used when Auth0 acts as the service provider in an IdP-initiated SSO flow. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionIdpInitiatedClientProtocol + { + + /// OpenID Connect protocol. + [JsonStringEnumMemberName("oidc")] + Oidc, + + /// SAML 2.0 protocol. + [JsonStringEnumMemberName("samlp")] + Samlp, + + /// WS-Federation protocol. + [JsonStringEnumMemberName("wsfed")] + WsFed, + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionMappingModeEnumOidc.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionMappingModeEnumOidc.cs new file mode 100644 index 0000000..ee53d09 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionMappingModeEnumOidc.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionMappingModeEnumOidc +{ + + [JsonStringEnumMemberName("bind_all")] + BindAll, + + [JsonStringEnumMemberName("use_map")] + UseMap + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionMappingModeEnumOkta.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionMappingModeEnumOkta.cs new file mode 100644 index 0000000..515eeb2 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionMappingModeEnumOkta.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionMappingModeEnumOkta +{ + + [JsonStringEnumMemberName("basic_profile")] + BasicProfile, + + [JsonStringEnumMemberName("use_map")] + UseMap + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionMfa.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionMfa.cs new file mode 100644 index 0000000..7ba1aa8 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionMfa.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionMfa +{ + + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + + [JsonPropertyName("return_enroll_settings")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReturnEnrollSettings { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptions.cs new file mode 100644 index 0000000..fb357ff --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptions.cs @@ -0,0 +1,245 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Set of typed configuration options. + /// + public record V2alpha1ConnectionOptions + { + + /// + /// Strategy-specific options for the auth0 (database) connection strategy. + /// + [JsonPropertyName("auth0")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAuth0? Auth0 { get; set; } + + /// + /// Strategy-specific options for the ad (Active Directory / LDAP) connection strategy. + /// + [JsonPropertyName("ad")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAd? Ad { get; set; } + + /// + /// Strategy-specific options for the adfs (Active Directory Federation Services) connection strategy. + /// + [JsonPropertyName("adfs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAdfs? Adfs { get; set; } + + /// + /// Strategy-specific options for the auth0-oidc connection strategy (Auth0 tenant as OIDC provider). + /// + [JsonPropertyName("auth0Oidc")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAuth0Oidc? Auth0Oidc { get; set; } + + /// + /// Strategy-specific options for the waad (Azure Active Directory) connection strategy. + /// + [JsonPropertyName("azureAd")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAzureAd? AzureAd { get; set; } + + /// + /// Strategy-specific options for the bitbucket social connection strategy. + /// + [JsonPropertyName("bitbucket")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsBitbucket? Bitbucket { get; set; } + + /// + /// Strategy-specific options for the box social connection strategy. + /// + [JsonPropertyName("box")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsBox? Box { get; set; } + + /// + /// Strategy-specific options for the dropbox social connection strategy. + /// + [JsonPropertyName("dropbox")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsDropbox? Dropbox { get; set; } + + /// + /// Strategy-specific options for the email (passwordless) connection strategy. + /// + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsEmail? Email { get; set; } + + /// + /// Strategy-specific options for the evernote social connection strategy. + /// + [JsonPropertyName("evernote")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsEvernote? Evernote { get; set; } + + /// + /// Strategy-specific options for the evernote-sandbox social connection strategy. + /// + [JsonPropertyName("evernoteSandbox")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsEvernote? EvernoteSandbox { get; set; } + + /// + /// Strategy-specific options for the exact social connection strategy. + /// + [JsonPropertyName("exact")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsExact? Exact { get; set; } + + /// + /// Strategy-specific options for the facebook social connection strategy. + /// + [JsonPropertyName("facebook")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsFacebook? Facebook { get; set; } + + /// + /// Strategy-specific options for the github social connection strategy. + /// + [JsonPropertyName("gitHub")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsGitHub? GitHub { get; set; } + + /// + /// Strategy-specific options for the google-apps (Google Workspace) enterprise connection strategy. + /// + [JsonPropertyName("googleApps")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsGoogleApps? GoogleApps { get; set; } + + /// + /// Strategy-specific options for the google-oauth2 social connection strategy. + /// + [JsonPropertyName("googleOAuth2")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsGoogleOAuth2? GoogleOAuth2 { get; set; } + + /// + /// Strategy-specific options for the linkedin social connection strategy. + /// + [JsonPropertyName("linkedin")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsLinkedin? Linkedin { get; set; } + + /// + /// Strategy-specific options for a generic oauth1 connection strategy. + /// + [JsonPropertyName("oAuth1")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsOAuth1? OAuth1 { get; set; } + + /// + /// Strategy-specific options for a generic oauth2 connection strategy. + /// + [JsonPropertyName("oAuth2")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsOAuth2? OAuth2 { get; set; } + + /// + /// Strategy-specific options for the office365 enterprise connection strategy. + /// + [JsonPropertyName("office365")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsOffice365? Office365 { get; set; } + + /// + /// Strategy-specific options for a generic oidc connection strategy. + /// + [JsonPropertyName("oidc")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsOidc? Oidc { get; set; } + + /// + /// Strategy-specific options for the okta enterprise connection strategy. + /// + [JsonPropertyName("okta")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsOkta? Okta { get; set; } + + /// + /// Strategy-specific options for the paypal social connection strategy. + /// + [JsonPropertyName("paypal")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsPaypal? Paypal { get; set; } + + /// + /// Strategy-specific options for the paypal-sandbox social connection strategy. + /// + [JsonPropertyName("paypalSandbox")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsPaypal? PaypalSandbox { get; set; } + + /// + /// Strategy-specific options for the pingfederate enterprise connection strategy. + /// + [JsonPropertyName("pingFederate")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsPingFederate? PingFederate { get; set; } + + /// + /// Strategy-specific options for the salesforce social connection strategy. + /// + [JsonPropertyName("salesforce")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsSalesforce? Salesforce { get; set; } + + /// + /// Strategy-specific options for the salesforce-community social connection strategy. + /// + [JsonPropertyName("salesforceCommunity")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsSalesforceCommunity? SalesforceCommunity { get; set; } + + /// + /// Strategy-specific options for the salesforce-sandbox social connection strategy. + /// + [JsonPropertyName("salesforceSandbox")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsSalesforce? SalesforceSandbox { get; set; } + + /// + /// Strategy-specific options for a samlp (SAML Identity Provider) connection strategy. + /// + [JsonPropertyName("saml")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsSaml? Saml { get; set; } + + /// + /// Strategy-specific options for the sms (passwordless) connection strategy. + /// + [JsonPropertyName("sms")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsSms? Sms { get; set; } + + /// + /// Strategy-specific options for the twitter social connection strategy. + /// + [JsonPropertyName("twitter")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsTwitter? Twitter { get; set; } + + /// + /// Strategy-specific options for the windowslive social connection strategy. + /// + [JsonPropertyName("windowsLive")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsWindowsLive? WindowsLive { get; set; } + + /// + /// Strategy-specific options for the yahoo social connection strategy. + /// + [JsonPropertyName("yahoo")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsYahoo? Yahoo { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAd.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAd.cs new file mode 100644 index 0000000..6e364d6 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAd.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsAd +{ + + [JsonPropertyName("agentIP")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AgentIp { get; set; } + + [JsonPropertyName("agentMode")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AgentMode { get; set; } + + [JsonPropertyName("agentVersion")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AgentVersion { get; set; } + + [JsonPropertyName("brute_force_protection")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? BruteForceProtection { get; set; } + + [JsonPropertyName("certAuth")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? CertAuth { get; set; } + + [JsonPropertyName("certs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Certs { get; set; } + + [JsonPropertyName("disable_cache")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DisableCache { get; set; } + + [JsonPropertyName("disable_self_service_change_password")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DisableSelfServiceChangePassword { get; set; } + + [JsonPropertyName("domain_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DomainAliases { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("ips")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Ips { get; set; } + + [JsonPropertyName("kerberos")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Kerberos { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("signInEndpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SignInEndpoint { get; set; } + + [JsonPropertyName("tenant_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantDomain { get; set; } + + [JsonPropertyName("thumbprints")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Thumbprints { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAdfs.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAdfs.cs new file mode 100644 index 0000000..7ae9c61 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAdfs.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsAdfs +{ + + [JsonPropertyName("adfs_server")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AdfsServer { get; set; } + + [JsonPropertyName("domain_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DomainAliases { get; set; } + + [JsonPropertyName("entityId")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? EntityId { get; set; } + + [JsonPropertyName("fedMetadataXml")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? FedMetadataXml { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("prev_thumbprints")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? PrevThumbprints { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("should_trust_email_verified_connection")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum? ShouldTrustEmailVerifiedConnection { get; set; } + + [JsonPropertyName("signInEndpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SignInEndpoint { get; set; } + + [JsonPropertyName("tenant_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantDomain { get; set; } + + [JsonPropertyName("thumbprints")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Thumbprints { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("user_id_attribute")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UserIdAttribute { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAmazon.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAmazon.cs new file mode 100644 index 0000000..8344673 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAmazon.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsAmazon +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("postal_code")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PostalCode { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsApple.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsApple.cs new file mode 100644 index 0000000..8f70610 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsApple.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsApple +{ + + [JsonPropertyName("app_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AppSecret { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Email { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("kid")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Kid { get; set; } + + [JsonPropertyName("name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Name { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("team_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TeamId { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAssertionDecryptionSettings.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAssertionDecryptionSettings.cs new file mode 100644 index 0000000..0fd699f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAssertionDecryptionSettings.cs @@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Settings that control decryption of incoming SAML assertions. + /// + public record V2alpha1ConnectionOptionsAssertionDecryptionSettings + { + + /// + /// When true, Auth0 will attempt to decrypt incoming SAML assertions. + /// + [JsonPropertyName("decryptAssertion")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DecryptAssertion { get; set; } + + /// + /// Algorithm profile used to decrypt the assertion content. + /// + [JsonPropertyName("decryptionAlgorithm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAssertionDecryptionAlgorithmProfile? DecryptionAlgorithm { get; set; } + + /// + /// Algorithm used to decrypt the encrypted key in the assertion (e.g. rsa-oaep-mgf1p, rsa1_5). + /// + [JsonPropertyName("keyEncryptionAlgorithm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? KeyEncryptionAlgorithm { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeAllowedTypes.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeAllowedTypes.cs new file mode 100644 index 0000000..7385e9d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeAllowedTypes.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Restricts the character types permitted in a username attribute value. + /// + public record V2alpha1ConnectionOptionsAttributeAllowedTypes + { + + /// + /// When true, the attribute value may be an email address. + /// + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Email { get; set; } + + /// + /// When true, the attribute value may be a phone number. + /// + [JsonPropertyName("phone_number")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PhoneNumber { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeIdentifier.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeIdentifier.cs new file mode 100644 index 0000000..ee2a0f1 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeIdentifier.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Controls whether an attribute can be used as a login identifier. + /// + public record V2alpha1ConnectionOptionsAttributeIdentifier + { + + /// + /// When true, this attribute is active as a login identifier. + /// + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeMap.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeMap.cs new file mode 100644 index 0000000..1882ed3 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeMap.cs @@ -0,0 +1,36 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Mapping configuration that controls how identity provider claims are translated to Auth0 user profile attributes. + /// + public record V2alpha1ConnectionOptionsAttributeMap + { + + /// + /// Controls how claims are mapped. Can be use_map to apply the custom mapping, + /// or bind_all to pass all claims through without mapping. + /// + [JsonPropertyName("mapping_mode")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? MappingMode { get; set; } + + /// + /// Space-separated list of claims to request from the UserInfo endpoint. + /// + [JsonPropertyName("userinfo_scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UserinfoScope { get; set; } + + /// + /// Maps Auth0 user profile attribute names to identity provider claim names. + /// + [JsonPropertyName("attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public System.Collections.Generic.Dictionary? Attributes { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeStatus.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeStatus.cs new file mode 100644 index 0000000..f528cf9 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeStatus.cs @@ -0,0 +1,27 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Indicates whether a user attribute is required, optional, or inactive during signup. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionOptionsAttributeStatus + { + + /// The attribute must be provided at signup. + [JsonStringEnumMemberName("required")] + Required, + + /// The attribute may optionally be provided at signup. + [JsonStringEnumMemberName("optional")] + Optional, + + /// The attribute is disabled and not collected during signup. + [JsonStringEnumMemberName("inactive")] + Inactive + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeValidation.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeValidation.cs new file mode 100644 index 0000000..ecc7fa4 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributeValidation.cs @@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Validation rules for a user attribute, including length constraints and allowed character types. + /// + public record V2alpha1ConnectionOptionsAttributeValidation + { + + /// + /// Minimum number of characters allowed for the attribute value. + /// + [JsonPropertyName("min_length")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? MinLength { get; set; } + + /// + /// Maximum number of characters allowed for the attribute value. + /// + [JsonPropertyName("max_length")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? MaxLength { get; set; } + + /// + /// Restricts which character types (email, phone number) are permitted in the attribute value. + /// + [JsonPropertyName("allowed_types")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAttributeAllowedTypes? AllowedTypes { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributes.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributes.cs new file mode 100644 index 0000000..ce291fe --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAttributes.cs @@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Configuration for user identifier attributes (email, phone number, and username) supported by the connection. + /// + public record V2alpha1ConnectionOptionsAttributes + { + + /// + /// Email attribute configuration, including identifier and signup settings. + /// + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsEmailAttribute? Email { get; set; } + + /// + /// Phone number attribute configuration, including signup settings. + /// + [JsonPropertyName("phone_number")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsPhoneNumberAttribute? PhoneNumber { get; set; } + + /// + /// Username attribute configuration, including identifier, profile requirement, signup status, and validation rules. + /// + [JsonPropertyName("username")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsUsernameAttribute? Username { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAuth0.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAuth0.cs new file mode 100644 index 0000000..e40137a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAuth0.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsAuth0 +{ + + [JsonPropertyName("attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAttributes? Attributes { get; set; } + + [JsonPropertyName("authentication_methods")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAuthenticationMethods? AuthenticationMethods { get; set; } + + [JsonPropertyName("brute_force_protection")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? BruteForceProtection { get; set; } + + [JsonPropertyName("configuration")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? Configuration { get; set; } + + [JsonPropertyName("customScripts")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionCustomScripts? CustomScripts { get; set; } + + [JsonPropertyName("disable_self_service_change_password")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DisableSelfServiceChangePassword { get; set; } + + [JsonPropertyName("disable_signup")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DisableSignup { get; set; } + + [JsonPropertyName("enable_script_context")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? EnableScriptContext { get; set; } + + [JsonPropertyName("enabledDatabaseCustomization")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? EnabledDatabaseCustomization { get; set; } + + [JsonPropertyName("import_mode")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ImportMode { get; set; } + + [JsonPropertyName("mfa")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionMfa? Mfa { get; set; } + + [JsonPropertyName("passkey_options")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasskeyOptions? PasskeyOptions { get; set; } + + [JsonPropertyName("passwordPolicy")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordPolicyEnum? PasswordPolicy { get; set; } + + [JsonPropertyName("password_complexity_options")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordComplexityOptions? PasswordComplexityOptions { get; set; } + + [JsonPropertyName("password_dictionary")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordDictionaryOptions? PasswordDictionary { get; set; } + + [JsonPropertyName("password_history")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordHistoryOptions? PasswordHistory { get; set; } + + [JsonPropertyName("password_no_personal_info")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordNoPersonalInfoOptions? PasswordNoPersonalInfo { get; set; } + + [JsonPropertyName("password_options")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordOptions? PasswordOptions { get; set; } + + [JsonPropertyName("precedence")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionIdentifierPrecedenceEnum[]? Precedence { get; set; } + + [JsonPropertyName("realm_fallback")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RealmFallback { get; set; } + + [JsonPropertyName("requires_username")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RequiresUsername { get; set; } + + [JsonPropertyName("validation")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionValidationOptions? Validation { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAuth0Oidc.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAuth0Oidc.cs new file mode 100644 index 0000000..d1e8ed8 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAuth0Oidc.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsAuth0Oidc +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAuthenticationMethods.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAuthenticationMethods.cs new file mode 100644 index 0000000..695ee10 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAuthenticationMethods.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Specifies which authentication methods are enabled for the connection. + /// + public record V2alpha1ConnectionOptionsAuthenticationMethods + { + + /// + /// Password authentication method configuration. + /// + [JsonPropertyName("password")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsPasswordAuthenticationMethod? Password { get; set; } + + /// + /// Passkey (WebAuthn) authentication method configuration. + /// + [JsonPropertyName("passkey")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsPasskeyAuthenticationMethod? Passkey { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAzureAd.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAzureAd.cs new file mode 100644 index 0000000..4494070 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsAzureAd.cs @@ -0,0 +1,282 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsAzureAd +{ + + [JsonPropertyName("api_enable_users")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ApiEnableUsers { get; set; } + + [JsonPropertyName("app_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AppDomain { get; set; } + + [JsonPropertyName("app_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AppId { get; set; } + + [JsonPropertyName("basic_profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? BasicProfile { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("domain_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DomainAliases { get; set; } + + [JsonPropertyName("ext_access_token")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtAccessToken { get; set; } + + [JsonPropertyName("ext_account_enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtAccountEnabled { get; set; } + + [JsonPropertyName("ext_admin")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtAdmin { get; set; } + + [JsonPropertyName("ext_agreed_terms")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtAgreedTerms { get; set; } + + [JsonPropertyName("ext_assigned_licenses")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtAssignedLicenses { get; set; } + + [JsonPropertyName("ext_assigned_plans")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtAssignedPlans { get; set; } + + [JsonPropertyName("ext_azure_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtAzureId { get; set; } + + [JsonPropertyName("ext_city")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtCity { get; set; } + + [JsonPropertyName("ext_country")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtCountry { get; set; } + + [JsonPropertyName("ext_department")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtDepartment { get; set; } + + [JsonPropertyName("ext_dir_sync_enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtDirSyncEnabled { get; set; } + + [JsonPropertyName("ext_email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtEmail { get; set; } + + [JsonPropertyName("ext_expires_in")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtExpiresIn { get; set; } + + [JsonPropertyName("ext_family_name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtFamilyName { get; set; } + + [JsonPropertyName("ext_fax")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtFax { get; set; } + + [JsonPropertyName("ext_given_name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtGivenName { get; set; } + + [JsonPropertyName("ext_group_ids")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtGroupIds { get; set; } + + [JsonPropertyName("ext_groups")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtGroups { get; set; } + + [JsonPropertyName("ext_is_suspended")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtIsSuspended { get; set; } + + [JsonPropertyName("ext_job_title")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtJobTitle { get; set; } + + [JsonPropertyName("ext_last_sync")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtLastSync { get; set; } + + [JsonPropertyName("ext_mobile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtMobile { get; set; } + + [JsonPropertyName("ext_name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtName { get; set; } + + [JsonPropertyName("ext_nested_groups")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtNestedGroups { get; set; } + + [JsonPropertyName("ext_nickname")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtNickname { get; set; } + + [JsonPropertyName("ext_oid")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtOid { get; set; } + + [JsonPropertyName("ext_phone")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtPhone { get; set; } + + [JsonPropertyName("ext_physical_delivery_office_name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtPhysicalDeliveryOfficeName { get; set; } + + [JsonPropertyName("ext_postal_code")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtPostalCode { get; set; } + + [JsonPropertyName("ext_preferred_language")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtPreferredLanguage { get; set; } + + [JsonPropertyName("ext_profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtProfile { get; set; } + + [JsonPropertyName("ext_provisioned_plans")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtProvisionedPlans { get; set; } + + [JsonPropertyName("ext_provisioning_errors")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtProvisioningErrors { get; set; } + + [JsonPropertyName("ext_proxy_addresses")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtProxyAddresses { get; set; } + + [JsonPropertyName("ext_puid")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtPuid { get; set; } + + [JsonPropertyName("ext_refresh_token")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtRefreshToken { get; set; } + + [JsonPropertyName("ext_roles")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtRoles { get; set; } + + [JsonPropertyName("ext_state")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtState { get; set; } + + [JsonPropertyName("ext_street")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtStreet { get; set; } + + [JsonPropertyName("ext_telephoneNumber")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtTelephoneNumber { get; set; } + + [JsonPropertyName("ext_tenantid")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtTenantid { get; set; } + + [JsonPropertyName("ext_upn")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtUpn { get; set; } + + [JsonPropertyName("ext_usage_location")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtUsageLocation { get; set; } + + [JsonPropertyName("ext_user_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtUserId { get; set; } + + [JsonPropertyName("federated_connections_access_tokens")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionFederatedConnectionsAccessTokens? FederatedConnectionsAccessTokens { get; set; } + + [JsonPropertyName("granted")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Granted { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("identity_api")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionIdentityApiEnumAzureAd? IdentityApi { get; set; } + + [JsonPropertyName("max_groups_to_retrieve")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? MaxGroupsToRetrieve { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("should_trust_email_verified_connection")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum? ShouldTrustEmailVerifiedConnection { get; set; } + + [JsonPropertyName("tenant_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantDomain { get; set; } + + [JsonPropertyName("tenantId")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantId { get; set; } + + [JsonPropertyName("thumbprints")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Thumbprints { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("use_wsfed")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UseWsfed { get; set; } + + [JsonPropertyName("useCommonEndpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UseCommonEndpoint { get; set; } + + [JsonPropertyName("userid_attribute")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionUseridAttributeEnumAzureAd? UseridAttribute { get; set; } + + [JsonPropertyName("waad_protocol")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionWaadProtocolEnumAzureAd? WaadProtocol { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBaidu.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBaidu.cs new file mode 100644 index 0000000..17a38fe --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBaidu.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsBaidu +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBitbucket.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBitbucket.cs new file mode 100644 index 0000000..8f2e817 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBitbucket.cs @@ -0,0 +1,37 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsBitbucket +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBitly.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBitly.cs new file mode 100644 index 0000000..d1164fe --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBitly.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsBitly +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBox.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBox.cs new file mode 100644 index 0000000..7238425 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsBox.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsBox +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsClientCredentials.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsClientCredentials.cs new file mode 100644 index 0000000..e3f0abb --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsClientCredentials.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Common client credentials (client_id / client_secret) shared by many social and enterprise connection option types. + /// + public record V2alpha1ConnectionOptionsClientCredentials + { + + /// + /// OAuth 2.0 client ID registered with the identity provider. + /// + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + /// + /// OAuth 2.0 client secret registered with the identity provider. + /// + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCommon.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCommon.cs new file mode 100644 index 0000000..fbe0389 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCommon.cs @@ -0,0 +1,13 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsCommon +{ + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCommonOidc.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCommonOidc.cs new file mode 100644 index 0000000..9d862c9 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCommonOidc.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsCommonOidc +{ + + [JsonPropertyName("authorization_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AuthorizationEndpoint { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("connection_settings")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionConnectionSettings? ConnectionSettings { get; set; } + + [JsonPropertyName("domain_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DomainAliases { get; set; } + + [JsonPropertyName("dpop_signing_alg")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDpopSigningAlgEnum? DpopSigningAlg { get; set; } + + [JsonPropertyName("federated_connections_access_tokens")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionFederatedConnectionsAccessTokens? FederatedConnectionsAccessTokens { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("id_token_signed_response_algs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionIdTokenSignedResponseAlgEnum[]? IdTokenSignedResponseAlgs { get; set; } + + [JsonPropertyName("issuer")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Issuer { get; set; } + + [JsonPropertyName("jwks_uri")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? JwksUri { get; set; } + + [JsonPropertyName("oidc_metadata")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsOidcMetadata? OidcMetadata { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Scope { get; set; } + + [JsonPropertyName("send_back_channel_nonce")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SendBackChannelNonce { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("tenant_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantDomain { get; set; } + + [JsonPropertyName("token_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TokenEndpoint { get; set; } + + [JsonPropertyName("token_endpoint_auth_method")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTokenEndpointAuthMethodEnum? TokenEndpointAuthMethod { get; set; } + + [JsonPropertyName("token_endpoint_auth_signing_alg")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum? TokenEndpointAuthSigningAlg { get; set; } + + [JsonPropertyName("token_endpoint_jwtca_aud_format")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc? TokenEndpointJwtcaAudFormat { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("userinfo_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UserinfoEndpoint { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCommonSaml.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCommonSaml.cs new file mode 100644 index 0000000..c589983 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCommonSaml.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsCommonSaml +{ + + [JsonPropertyName("assertion_decryption_settings")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAssertionDecryptionSettings? AssertionDecryptionSettings { get; set; } + + [JsonPropertyName("cert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Cert { get; set; } + + [JsonPropertyName("decryptionKey")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDecryptionKeySaml? DecryptionKey { get; set; } + + [JsonPropertyName("digestAlgorithm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDigestAlgorithmEnumSaml? DigestAlgorithm { get; set; } + + [JsonPropertyName("domain_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DomainAliases { get; set; } + + [JsonPropertyName("entityId")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? EntityId { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("idpinitiated")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsIdpinitiatedSaml? Idpinitiated { get; set; } + + [JsonPropertyName("protocolBinding")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionProtocolBindingEnumSaml? ProtocolBinding { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("signInEndpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SignInEndpoint { get; set; } + + [JsonPropertyName("signSAMLRequest")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SignSamlRequest { get; set; } + + [JsonPropertyName("signatureAlgorithm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignatureAlgorithmEnumSaml? SignatureAlgorithm { get; set; } + + [JsonPropertyName("tenant_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantDomain { get; set; } + + [JsonPropertyName("thumbprints")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Thumbprints { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsConnectionSettings.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsConnectionSettings.cs new file mode 100644 index 0000000..972b34d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsConnectionSettings.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Additional connection-level settings for an OIDC connection. + /// + public record V2alpha1ConnectionOptionsConnectionSettings + { + + /// + /// PKCE (Proof Key for Code Exchange) configuration. Can be auto, disabled, or forced. + /// + [JsonPropertyName("pkce")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Pkce { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCustomScripts.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCustomScripts.cs new file mode 100644 index 0000000..feb57f2 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsCustomScripts.cs @@ -0,0 +1,68 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Custom script implementations for CRUD operations executed against a custom database connection. + /// + public record V2alpha1ConnectionOptionsCustomScripts + { + + /// + /// Script that validates user credentials against the custom database. + /// + [JsonPropertyName("login")] + public string? Login { get; set; } + + /// + /// Script that retrieves a user profile from the custom database by email or username. + /// + [JsonPropertyName("get_user")] + public string? GetUser { get; set; } + + /// + /// Script that deletes a user from the custom database. + /// + [JsonPropertyName("delete")] + public string? Delete { get; set; } + + /// + /// Script that changes a user's password in the custom database. + /// + [JsonPropertyName("change_password")] + public string? ChangePassword { get; set; } + + /// + /// Script that marks a user's email as verified in the custom database. + /// + [JsonPropertyName("verify")] + public string? Verify { get; set; } + + /// + /// Script that creates a new user in the custom database. + /// + [JsonPropertyName("create")] + public string? Create { get; set; } + + /// + /// Script that updates a user's username in the custom database. + /// + [JsonPropertyName("change_username")] + public string? ChangeUsername { get; set; } + + /// + /// Script that updates a user's email address in the custom database. + /// + [JsonPropertyName("change_email")] + public string? ChangeEmail { get; set; } + + /// + /// Script that updates a user's phone number in the custom database. + /// + [JsonPropertyName("change_phone_number")] + public string? ChangePhoneNumber { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsDaccount.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsDaccount.cs new file mode 100644 index 0000000..6210698 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsDaccount.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsDaccount +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsDropbox.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsDropbox.cs new file mode 100644 index 0000000..3fe2eb3 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsDropbox.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsDropbox +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsDwolla.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsDwolla.cs new file mode 100644 index 0000000..262d26e --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsDwolla.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsDwolla +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEmail.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEmail.cs new file mode 100644 index 0000000..1e5ca4d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEmail.cs @@ -0,0 +1,37 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsEmail +{ + + [JsonPropertyName("authParams")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AuthParams { get; set; } + + [JsonPropertyName("brute_force_protection")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? BruteForceProtection { get; set; } + + [JsonPropertyName("disable_signup")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DisableSignup { get; set; } + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionEmailEmail? Email { get; set; } + + [JsonPropertyName("name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Name { get; set; } + + [JsonPropertyName("totp")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTotpEmail? Totp { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEmailAttribute.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEmailAttribute.cs new file mode 100644 index 0000000..a02cc5e --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEmailAttribute.cs @@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Configuration for the email address attribute on a database connection. + /// + public record V2alpha1ConnectionOptionsEmailAttribute + { + + /// + /// Controls whether email can be used as a login identifier. + /// + [JsonPropertyName("identifier")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAttributeIdentifier? Identifier { get; set; } + + /// + /// When true, the email address is required on the user profile. + /// + [JsonPropertyName("profile_required")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ProfileRequired { get; set; } + + /// + /// Signup status and verification settings for the email attribute. + /// + [JsonPropertyName("signup")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsEmailSignup? Signup { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEmailSignup.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEmailSignup.cs new file mode 100644 index 0000000..f683d8c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEmailSignup.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Signup configuration for the email attribute, controlling its requirement status and verification behaviour. + /// + public record V2alpha1ConnectionOptionsEmailSignup + { + + /// + /// Indicates whether the email attribute is required, optional, or inactive during signup. + /// + [JsonPropertyName("status")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAttributeStatus? Status { get; set; } + + /// + /// Email verification settings applied after signup. + /// + [JsonPropertyName("verification")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsVerification? Verification { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEvernote.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEvernote.cs new file mode 100644 index 0000000..3503093 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsEvernote.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsEvernote +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsExact.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsExact.cs new file mode 100644 index 0000000..cc9830a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsExact.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsExact +{ + + [JsonPropertyName("baseUrl")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? BaseUrl { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsFacebook.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsFacebook.cs new file mode 100644 index 0000000..4d1aabe --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsFacebook.cs @@ -0,0 +1,202 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsFacebook +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("ads_management")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AdsManagement { get; set; } + + [JsonPropertyName("ads_read")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AdsRead { get; set; } + + [JsonPropertyName("allow_context_profile_field")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AllowContextProfileField { get; set; } + + [JsonPropertyName("business_management")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? BusinessManagement { get; set; } + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Email { get; set; } + + [JsonPropertyName("groups_access_member_info")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GroupsAccessMemberInfo { get; set; } + + [JsonPropertyName("leads_retrieval")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? LeadsRetrieval { get; set; } + + [JsonPropertyName("manage_notifications")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ManageNotifications { get; set; } + + [JsonPropertyName("manage_pages")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ManagePages { get; set; } + + [JsonPropertyName("pages_manage_cta")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PagesManageCta { get; set; } + + [JsonPropertyName("pages_manage_instant_articles")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PagesManageInstantArticles { get; set; } + + [JsonPropertyName("pages_messaging")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PagesMessaging { get; set; } + + [JsonPropertyName("pages_messaging_phone_number")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PagesMessagingPhoneNumber { get; set; } + + [JsonPropertyName("pages_messaging_subscriptions")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PagesMessagingSubscriptions { get; set; } + + [JsonPropertyName("pages_show_list")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PagesShowList { get; set; } + + [JsonPropertyName("public_profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PublicProfile { get; set; } + + [JsonPropertyName("publish_actions")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PublishActions { get; set; } + + [JsonPropertyName("publish_pages")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PublishPages { get; set; } + + [JsonPropertyName("publish_to_groups")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PublishToGroups { get; set; } + + [JsonPropertyName("publish_video")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PublishVideo { get; set; } + + [JsonPropertyName("read_audience_network_insights")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReadAudienceNetworkInsights { get; set; } + + [JsonPropertyName("read_insights")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReadInsights { get; set; } + + [JsonPropertyName("read_mailbox")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReadMailbox { get; set; } + + [JsonPropertyName("read_page_mailboxes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReadPageMailboxes { get; set; } + + [JsonPropertyName("read_stream")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReadStream { get; set; } + + [JsonPropertyName("user_age_range")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserAgeRange { get; set; } + + [JsonPropertyName("user_birthday")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserBirthday { get; set; } + + [JsonPropertyName("user_events")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserEvents { get; set; } + + [JsonPropertyName("user_friends")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserFriends { get; set; } + + [JsonPropertyName("user_gender")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserGender { get; set; } + + [JsonPropertyName("user_groups")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserGroups { get; set; } + + [JsonPropertyName("user_hometown")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserHometown { get; set; } + + [JsonPropertyName("user_likes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserLikes { get; set; } + + [JsonPropertyName("user_link")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserLink { get; set; } + + [JsonPropertyName("user_location")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserLocation { get; set; } + + [JsonPropertyName("user_managed_groups")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserManagedGroups { get; set; } + + [JsonPropertyName("user_photos")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserPhotos { get; set; } + + [JsonPropertyName("user_posts")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserPosts { get; set; } + + [JsonPropertyName("user_status")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserStatus { get; set; } + + [JsonPropertyName("user_tagged_places")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserTaggedPlaces { get; set; } + + [JsonPropertyName("user_videos")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserVideos { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsFederatedConnectionsAccessTokens.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsFederatedConnectionsAccessTokens.cs new file mode 100644 index 0000000..91a838e --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsFederatedConnectionsAccessTokens.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Controls whether federated connection access tokens are enabled for the connection. + /// + public record V2alpha1ConnectionOptionsFederatedConnectionsAccessTokens + { + + /// + /// When true, federated connection access tokens are enabled. + /// + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsFitbit.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsFitbit.cs new file mode 100644 index 0000000..d6db961 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsFitbit.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsFitbit +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsGitHub.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsGitHub.cs new file mode 100644 index 0000000..f5309e1 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsGitHub.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsGitHub +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("admin_org")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AdminOrg { get; set; } + + [JsonPropertyName("admin_public_key")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AdminPublicKey { get; set; } + + [JsonPropertyName("admin_repo_hook")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AdminRepoHook { get; set; } + + [JsonPropertyName("delete_repo")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DeleteRepo { get; set; } + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Email { get; set; } + + [JsonPropertyName("follow")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Follow { get; set; } + + [JsonPropertyName("gist")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Gist { get; set; } + + [JsonPropertyName("notifications")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Notifications { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("public_repo")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PublicRepo { get; set; } + + [JsonPropertyName("read_org")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReadOrg { get; set; } + + [JsonPropertyName("read_public_key")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReadPublicKey { get; set; } + + [JsonPropertyName("read_repo_hook")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReadRepoHook { get; set; } + + [JsonPropertyName("read_user")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReadUser { get; set; } + + [JsonPropertyName("repo")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Repo { get; set; } + + [JsonPropertyName("repo_deployment")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RepoDeployment { get; set; } + + [JsonPropertyName("repo_status")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RepoStatus { get; set; } + + [JsonPropertyName("write_org")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? WriteOrg { get; set; } + + [JsonPropertyName("write_public_key")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? WritePublicKey { get; set; } + + [JsonPropertyName("write_repo_hook")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? WriteRepoHook { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsGoogleApps.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsGoogleApps.cs new file mode 100644 index 0000000..f64a8a3 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsGoogleApps.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsGoogleApps +{ + + [JsonPropertyName("admin_access_token")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AdminAccessToken { get; set; } + + [JsonPropertyName("admin_access_token_expiresin")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public DateTime? AdminAccessTokenExpiresin { get; set; } + + [JsonPropertyName("admin_refresh_token")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AdminRefreshToken { get; set; } + + [JsonPropertyName("allow_setting_login_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AllowSettingLoginScopes { get; set; } + + [JsonPropertyName("api_enable_groups")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ApiEnableGroups { get; set; } + + [JsonPropertyName("api_enable_users")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ApiEnableUsers { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Domain { get; set; } + + [JsonPropertyName("domain_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DomainAliases { get; set; } + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Email { get; set; } + + [JsonPropertyName("ext_agreed_terms")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtAgreedTerms { get; set; } + + [JsonPropertyName("ext_groups")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtGroups { get; set; } + + [JsonPropertyName("ext_groups_extended")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtGroupsExtended { get; set; } + + [JsonPropertyName("ext_is_admin")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtIsAdmin { get; set; } + + [JsonPropertyName("ext_is_suspended")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ExtIsSuspended { get; set; } + + [JsonPropertyName("federated_connections_access_tokens")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionFederatedConnectionsAccessTokens? FederatedConnectionsAccessTokens { get; set; } + + [JsonPropertyName("handle_login_from_social")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? HandleLoginFromSocial { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("map_user_id_to_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? MapUserIdToId { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("tenant_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantDomain { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsGoogleOAuth2.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsGoogleOAuth2.cs new file mode 100644 index 0000000..be0ce05 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsGoogleOAuth2.cs @@ -0,0 +1,306 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsGoogleOAuth2 +{ + + [JsonPropertyName("allowed_audiences")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? AllowedAudiences { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("adsense_management")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AdsenseManagement { get; set; } + + [JsonPropertyName("analytics")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Analytics { get; set; } + + [JsonPropertyName("blogger")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Blogger { get; set; } + + [JsonPropertyName("calendar")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Calendar { get; set; } + + [JsonPropertyName("calendar_addons_execute")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? CalendarAddonsExecute { get; set; } + + [JsonPropertyName("calendar_events")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? CalendarEvents { get; set; } + + [JsonPropertyName("calendar_events_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? CalendarEventsReadonly { get; set; } + + [JsonPropertyName("calendar_settings_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? CalendarSettingsReadonly { get; set; } + + [JsonPropertyName("chrome_web_store")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ChromeWebStore { get; set; } + + [JsonPropertyName("contacts")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Contacts { get; set; } + + [JsonPropertyName("contacts_new")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContactsNew { get; set; } + + [JsonPropertyName("contacts_other_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContactsOtherReadonly { get; set; } + + [JsonPropertyName("contacts_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContactsReadonly { get; set; } + + [JsonPropertyName("content_api_for_shopping")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContentApiForShopping { get; set; } + + [JsonPropertyName("coordinate")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Coordinate { get; set; } + + [JsonPropertyName("coordinate_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? CoordinateReadonly { get; set; } + + [JsonPropertyName("directory_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DirectoryReadonly { get; set; } + + [JsonPropertyName("document_list")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DocumentList { get; set; } + + [JsonPropertyName("drive")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Drive { get; set; } + + [JsonPropertyName("drive_activity")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DriveActivity { get; set; } + + [JsonPropertyName("drive_activity_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DriveActivityReadonly { get; set; } + + [JsonPropertyName("drive_appdata")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DriveAppdata { get; set; } + + [JsonPropertyName("drive_apps_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DriveAppsReadonly { get; set; } + + [JsonPropertyName("drive_file")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DriveFile { get; set; } + + [JsonPropertyName("drive_metadata")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DriveMetadata { get; set; } + + [JsonPropertyName("drive_metadata_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DriveMetadataReadonly { get; set; } + + [JsonPropertyName("drive_photos_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DrivePhotosReadonly { get; set; } + + [JsonPropertyName("drive_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DriveReadonly { get; set; } + + [JsonPropertyName("drive_scripts")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DriveScripts { get; set; } + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Email { get; set; } + + [JsonPropertyName("gmail")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Gmail { get; set; } + + [JsonPropertyName("gmail_compose")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GmailCompose { get; set; } + + [JsonPropertyName("gmail_insert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GmailInsert { get; set; } + + [JsonPropertyName("gmail_labels")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GmailLabels { get; set; } + + [JsonPropertyName("gmail_metadata")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GmailMetadata { get; set; } + + [JsonPropertyName("gmail_modify")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GmailModify { get; set; } + + [JsonPropertyName("gmail_new")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GmailNew { get; set; } + + [JsonPropertyName("gmail_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GmailReadonly { get; set; } + + [JsonPropertyName("gmail_send")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GmailSend { get; set; } + + [JsonPropertyName("gmail_settings_basic")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GmailSettingsBasic { get; set; } + + [JsonPropertyName("gmail_settings_sharing")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GmailSettingsSharing { get; set; } + + [JsonPropertyName("google_affiliate_network")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GoogleAffiliateNetwork { get; set; } + + [JsonPropertyName("google_books")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GoogleBooks { get; set; } + + [JsonPropertyName("google_cloud_storage")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GoogleCloudStorage { get; set; } + + [JsonPropertyName("google_drive")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GoogleDrive { get; set; } + + [JsonPropertyName("google_drive_files")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GoogleDriveFiles { get; set; } + + [JsonPropertyName("google_plus")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GooglePlus { get; set; } + + [JsonPropertyName("latitude_best")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? LatitudeBest { get; set; } + + [JsonPropertyName("latitude_city")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? LatitudeCity { get; set; } + + [JsonPropertyName("moderator")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Moderator { get; set; } + + [JsonPropertyName("offline_access")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? OfflineAccess { get; set; } + + [JsonPropertyName("orkut")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Orkut { get; set; } + + [JsonPropertyName("picasa_web")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PicasaWeb { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("sites")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Sites { get; set; } + + [JsonPropertyName("tasks")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Tasks { get; set; } + + [JsonPropertyName("tasks_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? TasksReadonly { get; set; } + + [JsonPropertyName("url_shortener")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UrlShortener { get; set; } + + [JsonPropertyName("webmaster_tools")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? WebmasterTools { get; set; } + + [JsonPropertyName("youtube")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Youtube { get; set; } + + [JsonPropertyName("youtube_channelmemberships_creator")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? YoutubeChannelmembershipsCreator { get; set; } + + [JsonPropertyName("youtube_new")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? YoutubeNew { get; set; } + + [JsonPropertyName("youtube_readonly")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? YoutubeReadonly { get; set; } + + [JsonPropertyName("youtube_upload")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? YoutubeUpload { get; set; } + + [JsonPropertyName("youtubepartner")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Youtubepartner { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.cs new file mode 100644 index 0000000..22c17e6 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml +{ + + [JsonStringEnumMemberName("oidc")] + Oidc, + + [JsonStringEnumMemberName("samlp")] + Samlp, + + [JsonStringEnumMemberName("wsfed")] + Wsfed + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsIdpinitiated.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsIdpinitiated.cs new file mode 100644 index 0000000..a63694f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsIdpinitiated.cs @@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Configuration for IdP-initiated SSO login flow on a SAML connection. + /// + public record V2alpha1ConnectionOptionsIdpinitiated + { + + /// + /// Client ID of the application to which the user is redirected after IdP-initiated login. + /// + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + /// + /// Protocol to use for the IdP-initiated callback. + /// + [JsonPropertyName("client_protocol")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionIdpInitiatedClientProtocol? ClientProtocol { get; set; } + + /// + /// Additional query string parameters to append to the IdP-initiated authorization request. + /// + [JsonPropertyName("client_authorizequery")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientAuthorizequery { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsIdpinitiatedSaml.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsIdpinitiatedSaml.cs new file mode 100644 index 0000000..afe0b2a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsIdpinitiatedSaml.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsIdpinitiatedSaml +{ + + [JsonPropertyName("client_authorizequery")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientAuthorizequery { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_protocol")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml? ClientProtocol { get; set; } + + [JsonPropertyName("enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enabled { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsInstagram.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsInstagram.cs new file mode 100644 index 0000000..34e2125 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsInstagram.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsInstagram +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsKerberos.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsKerberos.cs new file mode 100644 index 0000000..8a8aca3 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsKerberos.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Kerberos configuration for an Active Directory connection. + /// + public record V2alpha1ConnectionOptionsKerberos + { + + /// + /// When true, Kerberos integrated Windows authentication is enabled for the connection. + /// + [JsonPropertyName("enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enabled { get; set; } + + /// + /// IP address ranges (CIDR notation) from which Kerberos authentication is allowed. + /// + [JsonPropertyName("ips")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Ips { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsKeyPair.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsKeyPair.cs new file mode 100644 index 0000000..82f5f46 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsKeyPair.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// A PEM-encoded key/certificate pair used for signing or decryption on a SAML connection. + /// + public record V2alpha1ConnectionOptionsKeyPair + { + + /// + /// PEM-encoded private key. + /// + [JsonPropertyName("key")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Key { get; set; } + + /// + /// PEM-encoded X.509 certificate. + /// + [JsonPropertyName("cert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Cert { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsLine.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsLine.cs new file mode 100644 index 0000000..a581f44 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsLine.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsLine +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Email { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsLinkedin.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsLinkedin.cs new file mode 100644 index 0000000..77226e6 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsLinkedin.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsLinkedin +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("strategy_version")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? StrategyVersion { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("basic_profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? BasicProfile { get; set; } + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Email { get; set; } + + [JsonPropertyName("full_profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? FullProfile { get; set; } + + [JsonPropertyName("network")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Network { get; set; } + + [JsonPropertyName("openid")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Openid { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsMfa.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsMfa.cs new file mode 100644 index 0000000..3ba866f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsMfa.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// MFA configuration for a database connection. + /// + public record V2alpha1ConnectionOptionsMfa + { + + /// + /// When true, MFA is active for the connection. + /// + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + + /// + /// When true, enrollment settings are returned to the client during authentication. + /// + [JsonPropertyName("return_enroll_settings")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ReturnEnrollSettings { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth1.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth1.cs new file mode 100644 index 0000000..e8dc3c0 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth1.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsOAuth1 +{ + + [JsonPropertyName("accessTokenURL")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AccessTokenUrl { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("requestTokenURL")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? RequestTokenUrl { get; set; } + + [JsonPropertyName("scripts")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionScriptsOAuth1? Scripts { get; set; } + + [JsonPropertyName("signatureMethod")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignatureMethodOAuth1? SignatureMethod { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("userAuthorizationURL")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UserAuthorizationUrl { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth1Common.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth1Common.cs new file mode 100644 index 0000000..0b0a3cb --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth1Common.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsOAuth1Common +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth2.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth2.cs new file mode 100644 index 0000000..9eb270a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth2.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsOAuth2 +{ + + [JsonPropertyName("authParams")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? AuthParams { get; set; } + + [JsonPropertyName("authParamsMap")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? AuthParamsMap { get; set; } + + [JsonPropertyName("authorizationURL")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AuthorizationUrl { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("customHeaders")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? CustomHeaders { get; set; } + + [JsonPropertyName("fieldsMap")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? FieldsMap { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("logoutUrl")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? LogoutUrl { get; set; } + + [JsonPropertyName("pkce_enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PkceEnabled { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("scripts")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionScriptsOAuth2? Scripts { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("tokenURL")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TokenUrl { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("useOauthSpecScope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UseOauthSpecScope { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth2Common.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth2Common.cs new file mode 100644 index 0000000..69eec8d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOAuth2Common.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsOAuth2Common +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOffice365.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOffice365.cs new file mode 100644 index 0000000..4994440 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOffice365.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsOffice365 +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOidc.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOidc.cs new file mode 100644 index 0000000..7641587 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOidc.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsOidc +{ + + [JsonPropertyName("attribute_map")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAttributeMapOidc? AttributeMap { get; set; } + + [JsonPropertyName("discovery_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? DiscoveryUrl { get; set; } + + [JsonPropertyName("type")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTypeEnumOidc? Type { get; set; } + + [JsonPropertyName("authorization_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AuthorizationEndpoint { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("connection_settings")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionConnectionSettings? ConnectionSettings { get; set; } + + [JsonPropertyName("domain_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DomainAliases { get; set; } + + [JsonPropertyName("dpop_signing_alg")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDpopSigningAlgEnum? DpopSigningAlg { get; set; } + + [JsonPropertyName("federated_connections_access_tokens")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionFederatedConnectionsAccessTokens? FederatedConnectionsAccessTokens { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("id_token_signed_response_algs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionIdTokenSignedResponseAlgEnum[]? IdTokenSignedResponseAlgs { get; set; } + + [JsonPropertyName("issuer")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Issuer { get; set; } + + [JsonPropertyName("jwks_uri")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? JwksUri { get; set; } + + [JsonPropertyName("oidc_metadata")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsOidcMetadata? OidcMetadata { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Scope { get; set; } + + [JsonPropertyName("send_back_channel_nonce")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SendBackChannelNonce { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("tenant_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantDomain { get; set; } + + [JsonPropertyName("token_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TokenEndpoint { get; set; } + + [JsonPropertyName("token_endpoint_auth_method")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTokenEndpointAuthMethodEnum? TokenEndpointAuthMethod { get; set; } + + [JsonPropertyName("token_endpoint_auth_signing_alg")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum? TokenEndpointAuthSigningAlg { get; set; } + + [JsonPropertyName("token_endpoint_jwtca_aud_format")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc? TokenEndpointJwtcaAudFormat { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("userinfo_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UserinfoEndpoint { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOidcMetadata.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOidcMetadata.cs new file mode 100644 index 0000000..bb4e440 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOidcMetadata.cs @@ -0,0 +1,157 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsOidcMetadata +{ + + [JsonPropertyName("acr_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? AcrValuesSupported { get; set; } + + [JsonPropertyName("authorization_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AuthorizationEndpoint { get; set; } + + [JsonPropertyName("claim_types_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? ClaimTypesSupported { get; set; } + + [JsonPropertyName("claims_locales_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? ClaimsLocalesSupported { get; set; } + + [JsonPropertyName("claims_parameter_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ClaimsParameterSupported { get; set; } + + [JsonPropertyName("claims_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? ClaimsSupported { get; set; } + + [JsonPropertyName("display_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DisplayValuesSupported { get; set; } + + [JsonPropertyName("dpop_signing_alg_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DpopSigningAlgValuesSupported { get; set; } + + [JsonPropertyName("end_session_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? EndSessionEndpoint { get; set; } + + [JsonPropertyName("grant_types_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? GrantTypesSupported { get; set; } + + [JsonPropertyName("id_token_encryption_alg_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? IdTokenEncryptionAlgValuesSupported { get; set; } + + [JsonPropertyName("id_token_encryption_enc_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? IdTokenEncryptionEncValuesSupported { get; set; } + + [JsonPropertyName("id_token_signing_alg_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? IdTokenSigningAlgValuesSupported { get; set; } + + [JsonPropertyName("issuer")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Issuer { get; set; } + + [JsonPropertyName("jwks_uri")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? JwksUri { get; set; } + + [JsonPropertyName("op_policy_uri")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? OpPolicyUri { get; set; } + + [JsonPropertyName("op_tos_uri")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? OpTosUri { get; set; } + + [JsonPropertyName("registration_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? RegistrationEndpoint { get; set; } + + [JsonPropertyName("request_object_encryption_alg_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? RequestObjectEncryptionAlgValuesSupported { get; set; } + + [JsonPropertyName("request_object_encryption_enc_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? RequestObjectEncryptionEncValuesSupported { get; set; } + + [JsonPropertyName("request_object_signing_alg_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? RequestObjectSigningAlgValuesSupported { get; set; } + + [JsonPropertyName("request_parameter_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RequestParameterSupported { get; set; } + + [JsonPropertyName("request_uri_parameter_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RequestUriParameterSupported { get; set; } + + [JsonPropertyName("require_request_uri_registration")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RequireRequestUriRegistration { get; set; } + + [JsonPropertyName("response_modes_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? ResponseModesSupported { get; set; } + + [JsonPropertyName("response_types_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? ResponseTypesSupported { get; set; } + + [JsonPropertyName("scopes_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? ScopesSupported { get; set; } + + [JsonPropertyName("service_documentation")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ServiceDocumentation { get; set; } + + [JsonPropertyName("subject_types_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? SubjectTypesSupported { get; set; } + + [JsonPropertyName("token_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TokenEndpoint { get; set; } + + [JsonPropertyName("token_endpoint_auth_methods_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? TokenEndpointAuthMethodsSupported { get; set; } + + [JsonPropertyName("token_endpoint_auth_signing_alg_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? TokenEndpointAuthSigningAlgValuesSupported { get; set; } + + [JsonPropertyName("ui_locales_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? UiLocalesSupported { get; set; } + + [JsonPropertyName("userinfo_encryption_alg_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? UserinfoEncryptionAlgValuesSupported { get; set; } + + [JsonPropertyName("userinfo_encryption_enc_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? UserinfoEncryptionEncValuesSupported { get; set; } + + [JsonPropertyName("userinfo_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UserinfoEndpoint { get; set; } + + [JsonPropertyName("userinfo_signing_alg_values_supported")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? UserinfoSigningAlgValuesSupported { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOkta.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOkta.cs new file mode 100644 index 0000000..8e58a13 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsOkta.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsOkta +{ + + [JsonPropertyName("attribute_map")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAttributeMapOkta? AttributeMap { get; set; } + + [JsonPropertyName("domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Domain { get; set; } + + [JsonPropertyName("type")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTypeEnumOkta? Type { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + + [JsonPropertyName("authorization_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? AuthorizationEndpoint { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("connection_settings")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionConnectionSettings? ConnectionSettings { get; set; } + + [JsonPropertyName("domain_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DomainAliases { get; set; } + + [JsonPropertyName("dpop_signing_alg")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDpopSigningAlgEnum? DpopSigningAlg { get; set; } + + [JsonPropertyName("federated_connections_access_tokens")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionFederatedConnectionsAccessTokens? FederatedConnectionsAccessTokens { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("id_token_signed_response_algs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionIdTokenSignedResponseAlgEnum[]? IdTokenSignedResponseAlgs { get; set; } + + [JsonPropertyName("issuer")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Issuer { get; set; } + + [JsonPropertyName("jwks_uri")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? JwksUri { get; set; } + + [JsonPropertyName("oidc_metadata")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsOidcMetadata? OidcMetadata { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Scope { get; set; } + + [JsonPropertyName("send_back_channel_nonce")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SendBackChannelNonce { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("tenant_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantDomain { get; set; } + + [JsonPropertyName("token_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TokenEndpoint { get; set; } + + [JsonPropertyName("token_endpoint_auth_method")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTokenEndpointAuthMethodEnum? TokenEndpointAuthMethod { get; set; } + + [JsonPropertyName("token_endpoint_auth_signing_alg")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum? TokenEndpointAuthSigningAlg { get; set; } + + [JsonPropertyName("token_endpoint_jwtca_aud_format")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc? TokenEndpointJwtcaAudFormat { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("userinfo_endpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UserinfoEndpoint { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasskeyAuthenticationMethod.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasskeyAuthenticationMethod.cs new file mode 100644 index 0000000..c9cd1be --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasskeyAuthenticationMethod.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Enables or disables passkey (WebAuthn) authentication for the connection. + /// + public record V2alpha1ConnectionOptionsPasskeyAuthenticationMethod + { + + /// + /// When true, passkey authentication is allowed for this connection. + /// + [JsonPropertyName("enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enabled { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasskeyOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasskeyOptions.cs new file mode 100644 index 0000000..4b7382c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasskeyOptions.cs @@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Passkey-specific options controlling the challenge UI and enrollment behaviour for the connection. + /// + public record V2alpha1ConnectionOptionsPasskeyOptions + { + + /// + /// Determines the UI presented to users when authenticating with a passkey (both, autofill, or button). + /// + [JsonPropertyName("challenge_ui")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionChallengeUi? ChallengeUi { get; set; } + + /// + /// When true, users who log in with a password are offered the option to enroll a passkey. + /// + [JsonPropertyName("progressive_enrollment_enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ProgressiveEnrollmentEnabled { get; set; } + + /// + /// When true, users can enroll passkeys that are bound to their local device. + /// + [JsonPropertyName("local_enrollment_enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? LocalEnrollmentEnabled { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordAuthenticationMethod.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordAuthenticationMethod.cs new file mode 100644 index 0000000..a9198af --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordAuthenticationMethod.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Enables or disables password-based authentication for the connection. + /// + public record V2alpha1ConnectionOptionsPasswordAuthenticationMethod + { + + /// + /// When true, password authentication is allowed for this connection. + /// + [JsonPropertyName("enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enabled { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordComplexityOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordComplexityOptions.cs new file mode 100644 index 0000000..2c9bbdb --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordComplexityOptions.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Complexity requirements applied to passwords on a database connection. + /// + public record V2alpha1ConnectionOptionsPasswordComplexityOptions + { + + /// + /// Minimum number of characters required in a password. + /// + [JsonPropertyName("min_length")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? MinLength { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordDictionary.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordDictionary.cs new file mode 100644 index 0000000..264a787 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordDictionary.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Controls whether Auth0 rejects passwords found in a common-password dictionary, optionally extended with custom entries. + /// + public record V2alpha1ConnectionOptionsPasswordDictionary + { + + /// + /// When true, passwords that appear in the common-password dictionary are rejected. + /// + [JsonPropertyName("enable")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enable { get; set; } + + /// + /// Additional custom words to reject as passwords, supplementing the built-in dictionary. + /// + [JsonPropertyName("dictionary")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Dictionary { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordHistory.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordHistory.cs new file mode 100644 index 0000000..c30045e --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordHistory.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Controls whether previously used passwords are remembered and rejected during password changes. + /// + public record V2alpha1ConnectionOptionsPasswordHistory + { + + /// + /// When true, Auth0 keeps a history of past passwords and prevents reuse. + /// + [JsonPropertyName("enable")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enable { get; set; } + + /// + /// Number of previous passwords to retain and compare against. + /// + [JsonPropertyName("size")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Size { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordNoPersonalInfo.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordNoPersonalInfo.cs new file mode 100644 index 0000000..9a040ad --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordNoPersonalInfo.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Controls whether Auth0 rejects passwords that contain personal information such as the user's name or email address. + /// + public record V2alpha1ConnectionOptionsPasswordNoPersonalInfo + { + + /// + /// When true, passwords that contain the user's personal information are rejected. + /// + [JsonPropertyName("enable")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enable { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordPolicy.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordPolicy.cs new file mode 100644 index 0000000..8e008d0 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPasswordPolicy.cs @@ -0,0 +1,35 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Password strength policy level enforced for a database connection. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionOptionsPasswordPolicy + { + + /// No password policy is enforced. + [JsonStringEnumMemberName("none")] + None, + + /// Low strength: at least 1 character of any type. + [JsonStringEnumMemberName("low")] + Low, + + /// Fair strength: at least 6 characters including a lower-case letter, an upper-case letter, and a number. + [JsonStringEnumMemberName("fair")] + Fair, + + /// Good strength: at least 8 characters including a lower-case letter, an upper-case letter, a number, and a special character. + [JsonStringEnumMemberName("good")] + Good, + + /// Excellent strength: at least 10 characters including a lower-case letter, an upper-case letter, a number, and at least 3 different special characters. + [JsonStringEnumMemberName("excellent")] + Excellent + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPaypal.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPaypal.cs new file mode 100644 index 0000000..3586314 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPaypal.cs @@ -0,0 +1,49 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsPaypal +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("address")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Address { get; set; } + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Email { get; set; } + + [JsonPropertyName("phone")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Phone { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPhoneNumberAttribute.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPhoneNumberAttribute.cs new file mode 100644 index 0000000..f23553c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPhoneNumberAttribute.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Configuration for the phone number attribute on a database connection. + /// + public record V2alpha1ConnectionOptionsPhoneNumberAttribute + { + + /// + /// Signup status and verification settings for the phone number attribute. + /// + [JsonPropertyName("signup")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsPhoneNumberSignup? Signup { get; set; } + + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPhoneNumberSignup.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPhoneNumberSignup.cs new file mode 100644 index 0000000..fd864da --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPhoneNumberSignup.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Signup configuration for the phone number attribute, controlling its requirement status and verification behaviour. + /// + public record V2alpha1ConnectionOptionsPhoneNumberSignup + { + + /// + /// Indicates whether the phone number attribute is required, optional, or inactive during signup. + /// + [JsonPropertyName("status")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAttributeStatus? Status { get; set; } + + /// + /// Phone number verification settings applied after signup. + /// + [JsonPropertyName("verification")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsVerification? Verification { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPingFederate.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPingFederate.cs new file mode 100644 index 0000000..7c1428f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPingFederate.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsPingFederate +{ + + [JsonPropertyName("pingFederateBaseUrl")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? PingFederateBaseUrl { get; set; } + + [JsonPropertyName("signingCert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SigningCert { get; set; } + + [JsonPropertyName("assertion_decryption_settings")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAssertionDecryptionSettings? AssertionDecryptionSettings { get; set; } + + [JsonPropertyName("cert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Cert { get; set; } + + [JsonPropertyName("decryptionKey")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDecryptionKeySaml? DecryptionKey { get; set; } + + [JsonPropertyName("digestAlgorithm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDigestAlgorithmEnumSaml? DigestAlgorithm { get; set; } + + [JsonPropertyName("domain_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DomainAliases { get; set; } + + [JsonPropertyName("entityId")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? EntityId { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("idpinitiated")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsIdpinitiatedSaml? Idpinitiated { get; set; } + + [JsonPropertyName("protocolBinding")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionProtocolBindingEnumSaml? ProtocolBinding { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("signInEndpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SignInEndpoint { get; set; } + + [JsonPropertyName("signSAMLRequest")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SignSamlRequest { get; set; } + + [JsonPropertyName("signatureAlgorithm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignatureAlgorithmEnumSaml? SignatureAlgorithm { get; set; } + + [JsonPropertyName("tenant_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantDomain { get; set; } + + [JsonPropertyName("thumbprints")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Thumbprints { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPlanningCenter.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPlanningCenter.cs new file mode 100644 index 0000000..e52ccbf --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPlanningCenter.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsPlanningCenter +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPrecedence.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPrecedence.cs new file mode 100644 index 0000000..828096c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsPrecedence.cs @@ -0,0 +1,27 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Identifier attribute used as the primary login identifier when multiple attributes are configured. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionOptionsPrecedence + { + + /// Email address is the primary identifier. + [JsonStringEnumMemberName("email")] + Email, + + /// Phone number is the primary identifier. + [JsonStringEnumMemberName("phone_number")] + PhoneNumber, + + /// Username is the primary identifier. + [JsonStringEnumMemberName("username")] + UserName + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsProtocolEnumTwitter.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsProtocolEnumTwitter.cs new file mode 100644 index 0000000..36b295a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsProtocolEnumTwitter.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionOptionsProtocolEnumTwitter +{ + + [JsonStringEnumMemberName("oauth1")] + Oauth1, + + [JsonStringEnumMemberName("oauth2")] + Oauth2 + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSalesforce.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSalesforce.cs new file mode 100644 index 0000000..cb5b553 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSalesforce.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsSalesforce +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSalesforceCommunity.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSalesforceCommunity.cs new file mode 100644 index 0000000..547265e --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSalesforceCommunity.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsSalesforceCommunity +{ + + [JsonPropertyName("community_base_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? CommunityBaseUrl { get; set; } + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSaml.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSaml.cs new file mode 100644 index 0000000..c95bde6 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSaml.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsSaml +{ + + [JsonPropertyName("debug")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Debug { get; set; } + + [JsonPropertyName("deflate")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Deflate { get; set; } + + [JsonPropertyName("destinationUrl")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? DestinationUrl { get; set; } + + [JsonPropertyName("disableSignout")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DisableSignout { get; set; } + + [JsonPropertyName("fieldsMap")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? FieldsMap { get; set; } + + [JsonPropertyName("global_token_revocation_jwt_iss")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? GlobalTokenRevocationJwtIss { get; set; } + + [JsonPropertyName("global_token_revocation_jwt_sub")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? GlobalTokenRevocationJwtSub { get; set; } + + [JsonPropertyName("metadataUrl")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? MetadataUrl { get; set; } + + [JsonPropertyName("metadataXml")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? MetadataXml { get; set; } + + [JsonPropertyName("recipientUrl")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? RecipientUrl { get; set; } + + [JsonPropertyName("requestTemplate")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? RequestTemplate { get; set; } + + [JsonPropertyName("signingCert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SigningCert { get; set; } + + [JsonPropertyName("signing_key")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSigningKeySaml? SigningKey { get; set; } + + [JsonPropertyName("signOutEndpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SignOutEndpoint { get; set; } + + [JsonPropertyName("user_id_attribute")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? UserIdAttribute { get; set; } + + [JsonPropertyName("assertion_decryption_settings")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAssertionDecryptionSettings? AssertionDecryptionSettings { get; set; } + + [JsonPropertyName("cert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Cert { get; set; } + + [JsonPropertyName("decryptionKey")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDecryptionKeySaml? DecryptionKey { get; set; } + + [JsonPropertyName("digestAlgorithm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionDigestAlgorithmEnumSaml? DigestAlgorithm { get; set; } + + [JsonPropertyName("domain_aliases")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? DomainAliases { get; set; } + + [JsonPropertyName("entityId")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? EntityId { get; set; } + + [JsonPropertyName("icon_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IconUrl { get; set; } + + [JsonPropertyName("idpinitiated")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsIdpinitiatedSaml? Idpinitiated { get; set; } + + [JsonPropertyName("protocolBinding")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionProtocolBindingEnumSaml? ProtocolBinding { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("signInEndpoint")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? SignInEndpoint { get; set; } + + [JsonPropertyName("signSAMLRequest")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SignSamlRequest { get; set; } + + [JsonPropertyName("signatureAlgorithm")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignatureAlgorithmEnumSaml? SignatureAlgorithm { get; set; } + + [JsonPropertyName("tenant_domain")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TenantDomain { get; set; } + + [JsonPropertyName("thumbprints")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Thumbprints { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsScripts.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsScripts.cs new file mode 100644 index 0000000..64d6647 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsScripts.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Custom scripts attached to a social or OAuth connection strategy. + /// + public record V2alpha1ConnectionOptionsScripts + { + + /// + /// JavaScript function that maps the raw identity-provider profile response to an Auth0 user profile. + /// + [JsonPropertyName("fetchUserProfile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? FetchUserProfile { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSharepoint.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSharepoint.cs new file mode 100644 index 0000000..6f184ca --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSharepoint.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsSharepoint +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsShop.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsShop.cs new file mode 100644 index 0000000..4dcac96 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsShop.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsShop +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsShopify.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsShopify.cs new file mode 100644 index 0000000..6d8e54f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsShopify.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsShopify +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSms.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSms.cs new file mode 100644 index 0000000..b0ac67f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSms.cs @@ -0,0 +1,69 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsSms +{ + + [JsonPropertyName("brute_force_protection")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? BruteForceProtection { get; set; } + + [JsonPropertyName("disable_signup")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DisableSignup { get; set; } + + [JsonPropertyName("forward_req_info")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ForwardReqInfo { get; set; } + + [JsonPropertyName("from")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? From { get; set; } + + [JsonPropertyName("gateway_authentication")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionGatewayAuthenticationSms? GatewayAuthentication { get; set; } + + [JsonPropertyName("gateway_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? GatewayUrl { get; set; } + + [JsonPropertyName("messaging_service_sid")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? MessagingServiceSid { get; set; } + + [JsonPropertyName("name")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Name { get; set; } + + [JsonPropertyName("provider")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionProviderEnumSms? Provider { get; set; } + + [JsonPropertyName("syntax")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTemplateSyntaxEnumSms? Syntax { get; set; } + + [JsonPropertyName("template")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Template { get; set; } + + [JsonPropertyName("totp")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionTotpSms? Totp { get; set; } + + [JsonPropertyName("twilio_sid")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TwilioSid { get; set; } + + [JsonPropertyName("twilio_token")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? TwilioToken { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSoundcloud.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSoundcloud.cs new file mode 100644 index 0000000..64b7624 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsSoundcloud.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsSoundcloud +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsThirtySevenSignals.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsThirtySevenSignals.cs new file mode 100644 index 0000000..f9c700c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsThirtySevenSignals.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsThirtySevenSignals +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsTwitter.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsTwitter.cs new file mode 100644 index 0000000..0468cbc --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsTwitter.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsTwitter +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("protocol")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsProtocolEnumTwitter? Protocol { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("offline_access")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? OfflineAccess { get; set; } + + [JsonPropertyName("profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Profile { get; set; } + + [JsonPropertyName("tweet_read")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? TweetRead { get; set; } + + [JsonPropertyName("users_read")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UsersRead { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUntappd.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUntappd.cs new file mode 100644 index 0000000..4d7c936 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUntappd.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsUntappd +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUserName.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUserName.cs new file mode 100644 index 0000000..109a912 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUserName.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Minimum and maximum length constraints for usernames in a database connection. + /// + public record V2alpha1ConnectionOptionsUserName + { + + /// + /// Minimum allowed username length. + /// + [JsonPropertyName("min")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Min { get; set; } + + /// + /// Maximum allowed username length. + /// + [JsonPropertyName("max")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Max { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUsernameAttribute.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUsernameAttribute.cs new file mode 100644 index 0000000..ac5bfb0 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUsernameAttribute.cs @@ -0,0 +1,42 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Configuration for the username attribute on a database connection. + /// + public record V2alpha1ConnectionOptionsUsernameAttribute + { + + /// + /// Controls whether the username can be used as a login identifier. + /// + [JsonPropertyName("identifier")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAttributeIdentifier? Identifier { get; set; } + + /// + /// When true, the username is required on the user profile. + /// + [JsonPropertyName("profile_required")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ProfileRequired { get; set; } + + /// + /// Signup status for the username attribute. + /// + [JsonPropertyName("signup")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsUsernameSignup? Signup { get; set; } + + /// + /// Length and character-type validation rules for the username. + /// + [JsonPropertyName("validation")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAttributeValidation? Validation { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUsernameSignup.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUsernameSignup.cs new file mode 100644 index 0000000..9044efc --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsUsernameSignup.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Signup configuration for the username attribute, controlling whether it is required, optional, or inactive. + /// + public record V2alpha1ConnectionOptionsUsernameSignup + { + + /// + /// Indicates whether the username attribute is required, optional, or inactive during signup. + /// + [JsonPropertyName("status")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsAttributeStatus? Status { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsValidation.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsValidation.cs new file mode 100644 index 0000000..bef1191 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsValidation.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Username validation constraints applied when creating or updating a user in a database connection. + /// + public record V2alpha1ConnectionOptionsValidation + { + + /// + /// Minimum and maximum length rules for usernames. + /// + [JsonPropertyName("username")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionOptionsUserName? UserName { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsVerification.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsVerification.cs new file mode 100644 index 0000000..ddf7c67 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsVerification.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Controls whether a verification step (e.g. email or SMS OTP) is active for a given signup attribute. + /// + public record V2alpha1ConnectionOptionsVerification + { + + /// + /// When true, a verification message is sent after signup for this attribute. + /// + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsVkontakte.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsVkontakte.cs new file mode 100644 index 0000000..b9bdd4f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsVkontakte.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsVkontakte +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsWeibo.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsWeibo.cs new file mode 100644 index 0000000..2ec5b4d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsWeibo.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsWeibo +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsWindowsLive.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsWindowsLive.cs new file mode 100644 index 0000000..56e371a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsWindowsLive.cs @@ -0,0 +1,274 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsWindowsLive +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("freeform_scopes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? FreeformScopes { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("strategy_version")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? StrategyVersion { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("applications")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Applications { get; set; } + + [JsonPropertyName("applications_create")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ApplicationsCreate { get; set; } + + [JsonPropertyName("basic")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Basic { get; set; } + + [JsonPropertyName("birthday")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Birthday { get; set; } + + [JsonPropertyName("calendars")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Calendars { get; set; } + + [JsonPropertyName("calendars_update")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? CalendarsUpdate { get; set; } + + [JsonPropertyName("contacts_birthday")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContactsBirthday { get; set; } + + [JsonPropertyName("contacts_calendars")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContactsCalendars { get; set; } + + [JsonPropertyName("contacts_create")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContactsCreate { get; set; } + + [JsonPropertyName("contacts_photos")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContactsPhotos { get; set; } + + [JsonPropertyName("contacts_skydrive")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ContactsSkydrive { get; set; } + + [JsonPropertyName("directory_accessasuser_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DirectoryAccessasuserAll { get; set; } + + [JsonPropertyName("directory_read_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DirectoryReadAll { get; set; } + + [JsonPropertyName("directory_readwrite_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DirectoryReadwriteAll { get; set; } + + [JsonPropertyName("emails")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Emails { get; set; } + + [JsonPropertyName("events_create")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? EventsCreate { get; set; } + + [JsonPropertyName("graph_calendars")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphCalendars { get; set; } + + [JsonPropertyName("graph_calendars_update")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphCalendarsUpdate { get; set; } + + [JsonPropertyName("graph_contacts")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphContacts { get; set; } + + [JsonPropertyName("graph_contacts_update")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphContactsUpdate { get; set; } + + [JsonPropertyName("graph_device")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphDevice { get; set; } + + [JsonPropertyName("graph_device_command")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphDeviceCommand { get; set; } + + [JsonPropertyName("graph_emails")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphEmails { get; set; } + + [JsonPropertyName("graph_emails_update")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphEmailsUpdate { get; set; } + + [JsonPropertyName("graph_files")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphFiles { get; set; } + + [JsonPropertyName("graph_files_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphFilesAll { get; set; } + + [JsonPropertyName("graph_files_all_update")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphFilesAllUpdate { get; set; } + + [JsonPropertyName("graph_files_update")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphFilesUpdate { get; set; } + + [JsonPropertyName("graph_notes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphNotes { get; set; } + + [JsonPropertyName("graph_notes_create")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphNotesCreate { get; set; } + + [JsonPropertyName("graph_notes_update")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphNotesUpdate { get; set; } + + [JsonPropertyName("graph_tasks")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphTasks { get; set; } + + [JsonPropertyName("graph_tasks_update")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphTasksUpdate { get; set; } + + [JsonPropertyName("graph_user")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphUser { get; set; } + + [JsonPropertyName("graph_user_activity")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphUserActivity { get; set; } + + [JsonPropertyName("graph_user_update")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GraphUserUpdate { get; set; } + + [JsonPropertyName("group_read_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GroupReadAll { get; set; } + + [JsonPropertyName("group_readwrite_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? GroupReadwriteAll { get; set; } + + [JsonPropertyName("mail_readwrite_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? MailReadwriteAll { get; set; } + + [JsonPropertyName("mail_send")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? MailSend { get; set; } + + [JsonPropertyName("messenger")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Messenger { get; set; } + + [JsonPropertyName("offline_access")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? OfflineAccess { get; set; } + + [JsonPropertyName("phone_numbers")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PhoneNumbers { get; set; } + + [JsonPropertyName("photos")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Photos { get; set; } + + [JsonPropertyName("postal_addresses")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PostalAddresses { get; set; } + + [JsonPropertyName("rolemanagement_read_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RolemanagementReadAll { get; set; } + + [JsonPropertyName("rolemanagement_readwrite_directory")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RolemanagementReadwriteDirectory { get; set; } + + [JsonPropertyName("share")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Share { get; set; } + + [JsonPropertyName("signin")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Signin { get; set; } + + [JsonPropertyName("sites_read_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SitesReadAll { get; set; } + + [JsonPropertyName("sites_readwrite_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SitesReadwriteAll { get; set; } + + [JsonPropertyName("skydrive")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Skydrive { get; set; } + + [JsonPropertyName("skydrive_update")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SkydriveUpdate { get; set; } + + [JsonPropertyName("team_readbasic_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? TeamReadbasicAll { get; set; } + + [JsonPropertyName("team_readwrite_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? TeamReadwriteAll { get; set; } + + [JsonPropertyName("user_read_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserReadAll { get; set; } + + [JsonPropertyName("user_readbasic_all")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? UserReadbasicAll { get; set; } + + [JsonPropertyName("work_profile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? WorkProfile { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsWordpress.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsWordpress.cs new file mode 100644 index 0000000..44345af --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsWordpress.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsWordpress +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsYahoo.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsYahoo.cs new file mode 100644 index 0000000..2878d00 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsYahoo.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsYahoo +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsYandex.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsYandex.cs new file mode 100644 index 0000000..fdf6990 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionOptionsYandex.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionOptionsYandex +{ + + [JsonPropertyName("client_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientId { get; set; } + + [JsonPropertyName("client_secret")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ClientSecret { get; set; } + + [JsonPropertyName("scope")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Scope { get; set; } + + [JsonPropertyName("set_user_root_attributes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSetUserRootAttributesEnum? SetUserRootAttributes { get; set; } + + [JsonPropertyName("upstream_params")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? UpstreamParams { get; set; } + + [JsonPropertyName("non_persistent_attrs")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? NonPersistentAttrs { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasskeyAuthenticationMethod.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasskeyAuthenticationMethod.cs new file mode 100644 index 0000000..b63e037 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasskeyAuthenticationMethod.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasskeyAuthenticationMethod +{ + + [JsonPropertyName("enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enabled { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasskeyChallengeUiEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasskeyChallengeUiEnum.cs new file mode 100644 index 0000000..20cc5fc --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasskeyChallengeUiEnum.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionPasskeyChallengeUiEnum +{ + + [JsonStringEnumMemberName("both")] + Both, + + [JsonStringEnumMemberName("autofill")] + Autofill, + + [JsonStringEnumMemberName("button")] + Button + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasskeyOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasskeyOptions.cs new file mode 100644 index 0000000..8f06a17 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasskeyOptions.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasskeyOptions +{ + + [JsonPropertyName("challenge_ui")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasskeyChallengeUiEnum? ChallengeUi { get; set; } + + [JsonPropertyName("progressive_enrollment_enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ProgressiveEnrollmentEnabled { get; set; } + + [JsonPropertyName("local_enrollment_enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? LocalEnrollmentEnabled { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordAuthenticationMethod.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordAuthenticationMethod.cs new file mode 100644 index 0000000..2220864 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordAuthenticationMethod.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasswordAuthenticationMethod +{ + + [JsonPropertyName("enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enabled { get; set; } + + [JsonPropertyName("api_behavior")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionApiBehaviorEnum? ApiBehavior { get; set; } + + [JsonPropertyName("signup_behavior")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignupBehaviorEnum? SignupBehavior { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordCharacterType.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordCharacterType.cs new file mode 100644 index 0000000..93f4e18 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordCharacterType.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionPasswordCharacterType + { + + [JsonStringEnumMemberName("uppercase")] + Uppercase, + + [JsonStringEnumMemberName("lowercase")] + Lowercase, + + [JsonStringEnumMemberName("number")] + Number, + + [JsonStringEnumMemberName("special")] + Special, + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordCharacterTypeEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordCharacterTypeEnum.cs new file mode 100644 index 0000000..1262215 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordCharacterTypeEnum.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionPasswordCharacterTypeEnum +{ + + [JsonStringEnumMemberName("uppercase")] + Uppercase, + + [JsonStringEnumMemberName("lowercase")] + Lowercase, + + [JsonStringEnumMemberName("number")] + Number, + + [JsonStringEnumMemberName("special")] + Special + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordCharacterTypeRulePolicyEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordCharacterTypeRulePolicyEnum.cs new file mode 100644 index 0000000..1f2cf81 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordCharacterTypeRulePolicyEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionPasswordCharacterTypeRulePolicyEnum +{ + + [JsonStringEnumMemberName("all")] + All, + + [JsonStringEnumMemberName("three_of_four")] + ThreeOfFour + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordComplexityOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordComplexityOptions.cs new file mode 100644 index 0000000..f5ecb92 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordComplexityOptions.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasswordComplexityOptions +{ + + [JsonPropertyName("min_length")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? MinLength { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordDefaultDictionariesEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordDefaultDictionariesEnum.cs new file mode 100644 index 0000000..c610698 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordDefaultDictionariesEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionPasswordDefaultDictionariesEnum +{ + + [JsonStringEnumMemberName("en10k")] + En10K, + + [JsonStringEnumMemberName("en100k")] + En100K + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordDictionaryOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordDictionaryOptions.cs new file mode 100644 index 0000000..6739461 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordDictionaryOptions.cs @@ -0,0 +1,17 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasswordDictionaryOptions +{ + + [JsonPropertyName("enable")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enable { get; set; } + + [JsonPropertyName("dictionary")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Dictionary { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordHistoryOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordHistoryOptions.cs new file mode 100644 index 0000000..3f6ffff --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordHistoryOptions.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasswordHistoryOptions +{ + + [JsonPropertyName("enable")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enable { get; set; } + + [JsonPropertyName("size")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Size { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordIdenticalCharactersPolicyEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordIdenticalCharactersPolicyEnum.cs new file mode 100644 index 0000000..4d7e818 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordIdenticalCharactersPolicyEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionPasswordIdenticalCharactersPolicyEnum +{ + + [JsonStringEnumMemberName("allow")] + Allow, + + [JsonStringEnumMemberName("block")] + Block + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordMaxLengthExceededPolicyEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordMaxLengthExceededPolicyEnum.cs new file mode 100644 index 0000000..84c8c1f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordMaxLengthExceededPolicyEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionPasswordMaxLengthExceededPolicyEnum +{ + + [JsonStringEnumMemberName("truncate")] + Truncate, + + [JsonStringEnumMemberName("error")] + Error + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordNoPersonalInfoOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordNoPersonalInfoOptions.cs new file mode 100644 index 0000000..2346263 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordNoPersonalInfoOptions.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasswordNoPersonalInfoOptions +{ + + [JsonPropertyName("enable")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enable { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptions.cs new file mode 100644 index 0000000..beb1bd4 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptions.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasswordOptions +{ + + [JsonPropertyName("complexity")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordOptionsComplexity? Complexity { get; set; } + + [JsonPropertyName("dictionary")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordOptionsDictionary? Dictionary { get; set; } + + [JsonPropertyName("history")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordOptionsHistory? History { get; set; } + + [JsonPropertyName("profile_data")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordOptionsProfileData? ProfileData { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsComplexity.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsComplexity.cs new file mode 100644 index 0000000..6f1d59f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsComplexity.cs @@ -0,0 +1,32 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasswordOptionsComplexity +{ + + [JsonPropertyName("min_length")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? MinLength { get; set; } + + [JsonPropertyName("character_types")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordCharacterTypeEnum[]? CharacterTypes { get; set; } + + [JsonPropertyName("character_type_rule")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordCharacterTypeRulePolicyEnum? CharacterTypeRule { get; set; } + + [JsonPropertyName("identical_characters")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordIdenticalCharactersPolicyEnum? IdenticalCharacters { get; set; } + + [JsonPropertyName("sequential_characters")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordSequentialCharactersPolicyEnum? SequentialCharacters { get; set; } + + [JsonPropertyName("max_length_exceeded")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordMaxLengthExceededPolicyEnum? MaxLengthExceeded { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsDictionary.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsDictionary.cs new file mode 100644 index 0000000..9d7f9bb --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsDictionary.cs @@ -0,0 +1,21 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasswordOptionsDictionary +{ + + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + + [JsonPropertyName("custom")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? Custom { get; set; } + + [JsonPropertyName("default")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionPasswordDefaultDictionariesEnum? Default { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsHistory.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsHistory.cs new file mode 100644 index 0000000..88db511 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsHistory.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasswordOptionsHistory +{ + + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + + [JsonPropertyName("size")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Size { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsProfileData.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsProfileData.cs new file mode 100644 index 0000000..6fbee03 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordOptionsProfileData.cs @@ -0,0 +1,17 @@ +using System; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPasswordOptionsProfileData +{ + + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + + [JsonPropertyName("blocked_fields")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string[]? BlockedFields { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordPolicyEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordPolicyEnum.cs new file mode 100644 index 0000000..f80440a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordPolicyEnum.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionPasswordPolicyEnum +{ + + [JsonStringEnumMemberName("none")] + None, + + [JsonStringEnumMemberName("low")] + Low, + + [JsonStringEnumMemberName("fair")] + Fair, + + [JsonStringEnumMemberName("good")] + Good, + + [JsonStringEnumMemberName("excellent")] + Excellent + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordSequentialCharactersPolicyEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordSequentialCharactersPolicyEnum.cs new file mode 100644 index 0000000..4a7f067 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPasswordSequentialCharactersPolicyEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionPasswordSequentialCharactersPolicyEnum +{ + + [JsonStringEnumMemberName("allow")] + Allow, + + [JsonStringEnumMemberName("block")] + Block + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPhoneAttribute.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPhoneAttribute.cs new file mode 100644 index 0000000..c364d73 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPhoneAttribute.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPhoneAttribute +{ + + [JsonPropertyName("identifier")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAttributeIdentifier? Identifier { get; set; } + + [JsonPropertyName("profile_required")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ProfileRequired { get; set; } + + [JsonPropertyName("signup")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignupVerified? Signup { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPhoneOtpAuthenticationMethod.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPhoneOtpAuthenticationMethod.cs new file mode 100644 index 0000000..927a656 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionPhoneOtpAuthenticationMethod.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionPhoneOtpAuthenticationMethod +{ + + [JsonPropertyName("enabled")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Enabled { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionProtocolBindingEnumSaml.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionProtocolBindingEnumSaml.cs new file mode 100644 index 0000000..245e605 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionProtocolBindingEnumSaml.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionProtocolBindingEnumSaml +{ + + [JsonStringEnumMemberName("urn_oasis_names_tc_saml20_bindings_http_post")] + UrnOasisNamesTcSaml20BindingsHttpPost, + + [JsonStringEnumMemberName("urn_oasis_names_tc_saml20_bindings_http_redirect")] + UrnOasisNamesTcSaml20BindingsHttpRedirect + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionProviderEnumSms.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionProviderEnumSms.cs new file mode 100644 index 0000000..0244893 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionProviderEnumSms.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionProviderEnumSms +{ + + [JsonStringEnumMemberName("sms_gateway")] + SmsGateway, + + [JsonStringEnumMemberName("twilio")] + Twilio + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionReadOnlyAdditionalProperties.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionReadOnlyAdditionalProperties.cs new file mode 100644 index 0000000..cf45b7f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionReadOnlyAdditionalProperties.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionReadOnlyAdditionalProperties +{ + + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSamlDigestAlgorithm.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSamlDigestAlgorithm.cs new file mode 100644 index 0000000..4ef4bcb --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSamlDigestAlgorithm.cs @@ -0,0 +1,23 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// XML digest algorithm used when generating SAML message digests. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionSamlDigestAlgorithm + { + + /// SHA-1 digest. + [JsonStringEnumMemberName("sha1")] + Sha1, + + /// SHA-256 digest. + [JsonStringEnumMemberName("sha256")] + Sha256, + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSamlProtocolBinding.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSamlProtocolBinding.cs new file mode 100644 index 0000000..5a2b694 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSamlProtocolBinding.cs @@ -0,0 +1,23 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// SAML protocol binding used for authentication requests and responses. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionSamlProtocolBinding + { + + /// HTTP POST binding. + [JsonStringEnumMemberName("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST")] + HttpPost, + + /// HTTP Redirect binding. + [JsonStringEnumMemberName("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect")] + HttpRedirect, + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSamlSignatureAlgorithm.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSamlSignatureAlgorithm.cs new file mode 100644 index 0000000..0728338 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSamlSignatureAlgorithm.cs @@ -0,0 +1,23 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// XML signature algorithm used when signing SAML requests or validating SAML responses. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionSamlSignatureAlgorithm + { + + /// RSA with SHA-1. + [JsonStringEnumMemberName("rsa-sha1")] + RsaSha1, + + /// RSA with SHA-256. + [JsonStringEnumMemberName("rsa-sha256")] + RsaSha256, + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionScriptsOAuth1.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionScriptsOAuth1.cs new file mode 100644 index 0000000..e3cb631 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionScriptsOAuth1.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionScriptsOAuth1 +{ + + [JsonPropertyName("fetchUserProfile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? FetchUserProfile { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionScriptsOAuth2.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionScriptsOAuth2.cs new file mode 100644 index 0000000..327f38e --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionScriptsOAuth2.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionScriptsOAuth2 +{ + + [JsonPropertyName("fetchUserProfile")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? FetchUserProfile { get; set; } + + [JsonPropertyName("getLogoutUrl")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? GetLogoutUrl { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSetUserRootAttributes.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSetUserRootAttributes.cs new file mode 100644 index 0000000..71f9cfc --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSetUserRootAttributes.cs @@ -0,0 +1,27 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Controls when Auth0 updates root-level user profile attributes from the identity provider. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionSetUserRootAttributes + { + + /// Root attributes are updated on every login. + [JsonStringEnumMemberName("on_each_login")] + OnEachLogin, + + /// Root attributes are only set on the user's first login. + [JsonStringEnumMemberName("on_first_login")] + OnFirstLogin, + + /// Root attributes are never updated from the identity provider. + [JsonStringEnumMemberName("never_on_login")] + NeverOnLogin + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSetUserRootAttributesEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSetUserRootAttributesEnum.cs new file mode 100644 index 0000000..95927e4 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSetUserRootAttributesEnum.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionSetUserRootAttributesEnum +{ + + [JsonStringEnumMemberName("on_each_login")] + OnEachLogin, + + [JsonStringEnumMemberName("on_first_login")] + OnFirstLogin, + + [JsonStringEnumMemberName("never_on_login")] + NeverOnLogin + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionShouldTrustEmailVerifiedConnection.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionShouldTrustEmailVerifiedConnection.cs new file mode 100644 index 0000000..1be8a54 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionShouldTrustEmailVerifiedConnection.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionShouldTrustEmailVerifiedConnection + { + + [JsonStringEnumMemberName("never_set_emails_as_verified")] + NeverSetEmailsAsVerified, + + [JsonStringEnumMemberName("always_set_emails_as_verified")] + AlwaysSetEmailsAsVerified, + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum.cs new file mode 100644 index 0000000..90565c1 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum +{ + + [JsonStringEnumMemberName("never_set_emails_as_verified")] + NeverSetEmailsAsVerified, + + [JsonStringEnumMemberName("always_set_emails_as_verified")] + AlwaysSetEmailsAsVerified + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignatureAlgorithmEnumSaml.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignatureAlgorithmEnumSaml.cs new file mode 100644 index 0000000..9ec32cc --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignatureAlgorithmEnumSaml.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionSignatureAlgorithmEnumSaml +{ + + [JsonStringEnumMemberName("rsa_sha1")] + RsaSha1, + + [JsonStringEnumMemberName("rsa_sha256")] + RsaSha256 + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignatureMethodOAuth1.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignatureMethodOAuth1.cs new file mode 100644 index 0000000..63223ae --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignatureMethodOAuth1.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionSignatureMethodOAuth1 +{ + + [JsonStringEnumMemberName("rsa_sha1")] + RsaSha1 + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSigningKeySaml.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSigningKeySaml.cs new file mode 100644 index 0000000..ae3cf5a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSigningKeySaml.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionSigningKeySaml +{ + + [JsonPropertyName("cert")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Cert { get; set; } + + [JsonPropertyName("key")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Key { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupBehaviorEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupBehaviorEnum.cs new file mode 100644 index 0000000..5948a17 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupBehaviorEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionSignupBehaviorEnum +{ + + [JsonStringEnumMemberName("allow")] + Allow, + + [JsonStringEnumMemberName("block")] + Block + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupSchema.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupSchema.cs new file mode 100644 index 0000000..8b33227 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupSchema.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionSignupSchema +{ + + [JsonPropertyName("status")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignupStatusEnum? Status { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupStatusEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupStatusEnum.cs new file mode 100644 index 0000000..7509056 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupStatusEnum.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionSignupStatusEnum +{ + + [JsonStringEnumMemberName("required")] + Required, + + [JsonStringEnumMemberName("optional")] + Optional, + + [JsonStringEnumMemberName("inactive")] + Inactive + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupVerification.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupVerification.cs new file mode 100644 index 0000000..424e2b5 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupVerification.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionSignupVerification +{ + + [JsonPropertyName("active")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Active { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupVerified.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupVerified.cs new file mode 100644 index 0000000..26f0718 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionSignupVerified.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionSignupVerified +{ + + [JsonPropertyName("status")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignupStatusEnum? Status { get; set; } + + [JsonPropertyName("verification")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignupVerification? Verification { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionStrategy.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionStrategy.cs new file mode 100644 index 0000000..fee765d --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionStrategy.cs @@ -0,0 +1,147 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Identity provider strategy for an Auth0 connection. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V2alpha1ConnectionStrategy + { + + /// Auth0 database connection. + [JsonStringEnumMemberName("auth0")] + Auth0, + + /// Active Directory / LDAP connection. + [JsonStringEnumMemberName("ad")] + Ad, + + /// Active Directory Federation Services connection. + [JsonStringEnumMemberName("adfs")] + Adfs, + + /// Auth0 tenant as OIDC provider connection. + [JsonStringEnumMemberName("auth0-oidc")] + Auth0Oidc, + + /// Azure Active Directory (Microsoft Entra ID) connection. + [JsonStringEnumMemberName("waad")] + AzureAd, + + /// Bitbucket social connection. + [JsonStringEnumMemberName("bitbucket")] + Bitbucket, + + /// Box social connection. + [JsonStringEnumMemberName("box")] + Box, + + /// Dropbox social connection. + [JsonStringEnumMemberName("dropbox")] + Dropbox, + + /// Email passwordless connection. + [JsonStringEnumMemberName("email")] + Email, + + /// Evernote social connection. + [JsonStringEnumMemberName("evernote")] + Evernote, + + /// Evernote sandbox social connection. + [JsonStringEnumMemberName("evernote-sandbox")] + EvernoteSandbox, + + /// Exact social connection. + [JsonStringEnumMemberName("exact")] + Exact, + + /// Facebook social connection. + [JsonStringEnumMemberName("facebook")] + Facebook, + + /// GitHub social connection. + [JsonStringEnumMemberName("github")] + GitHub, + + /// Google Workspace (Google Apps) enterprise connection. + [JsonStringEnumMemberName("google-apps")] + GoogleApps, + + /// Google OAuth2 social connection. + [JsonStringEnumMemberName("google-oauth2")] + GoogleOAuth2, + + /// LinkedIn social connection. + [JsonStringEnumMemberName("linkedin")] + Linkedin, + + /// Generic OAuth 1.0 connection. + [JsonStringEnumMemberName("oauth1")] + OAuth1, + + /// Generic OAuth 2.0 connection. + [JsonStringEnumMemberName("oauth2")] + OAuth2, + + /// Office 365 enterprise connection. + [JsonStringEnumMemberName("office365")] + Office365, + + /// Generic OpenID Connect connection. + [JsonStringEnumMemberName("oidc")] + Oidc, + + /// Okta enterprise connection. + [JsonStringEnumMemberName("okta")] + Okta, + + /// PayPal social connection. + [JsonStringEnumMemberName("paypal")] + Paypal, + + /// PayPal sandbox social connection. + [JsonStringEnumMemberName("paypal-sandbox")] + PaypalSandbox, + + /// PingFederate enterprise connection. + [JsonStringEnumMemberName("pingfederate")] + PingFederate, + + /// Salesforce social connection. + [JsonStringEnumMemberName("salesforce")] + Salesforce, + + /// Salesforce Community social connection. + [JsonStringEnumMemberName("salesforce-community")] + SalesforceCommunity, + + /// Salesforce sandbox social connection. + [JsonStringEnumMemberName("salesforce-sandbox")] + SalesforceSandbox, + + /// SAML Identity Provider connection. + [JsonStringEnumMemberName("samlp")] + Saml, + + /// SMS passwordless connection. + [JsonStringEnumMemberName("sms")] + Sms, + + /// Twitter social connection. + [JsonStringEnumMemberName("twitter")] + Twitter, + + /// Windows Live social connection. + [JsonStringEnumMemberName("windowslive")] + WindowsLive, + + /// Yahoo social connection. + [JsonStringEnumMemberName("yahoo")] + Yahoo, + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTemplateSyntaxEnumSms.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTemplateSyntaxEnumSms.cs new file mode 100644 index 0000000..85e31e6 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTemplateSyntaxEnumSms.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionTemplateSyntaxEnumSms +{ + + [JsonStringEnumMemberName("liquid")] + Liquid, + + [JsonStringEnumMemberName("md_with_macros")] + MdWithMacros + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTokenEndpointAuthMethodEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTokenEndpointAuthMethodEnum.cs new file mode 100644 index 0000000..1be182f --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTokenEndpointAuthMethodEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionTokenEndpointAuthMethodEnum +{ + + [JsonStringEnumMemberName("client_secret_post")] + ClientSecretPost, + + [JsonStringEnumMemberName("private_key_jwt")] + PrivateKeyJwt + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.cs new file mode 100644 index 0000000..336dd25 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.cs @@ -0,0 +1,30 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum +{ + + [JsonStringEnumMemberName("es256")] + Es256, + + [JsonStringEnumMemberName("es384")] + Es384, + + [JsonStringEnumMemberName("ps256")] + Ps256, + + [JsonStringEnumMemberName("ps384")] + Ps384, + + [JsonStringEnumMemberName("rs256")] + Rs256, + + [JsonStringEnumMemberName("rs384")] + Rs384, + + [JsonStringEnumMemberName("rs512")] + Rs512 + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc.cs new file mode 100644 index 0000000..4630c93 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc +{ + + [JsonStringEnumMemberName("issuer")] + Issuer, + + [JsonStringEnumMemberName("token_endpoint")] + TokenEndpoint + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTotpEmail.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTotpEmail.cs new file mode 100644 index 0000000..d65b739 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTotpEmail.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionTotpEmail +{ + + [JsonPropertyName("length")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Length { get; set; } + + [JsonPropertyName("time_step")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? TimeStep { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTotpSms.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTotpSms.cs new file mode 100644 index 0000000..b9180ab --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTotpSms.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionTotpSms +{ + + [JsonPropertyName("length")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Length { get; set; } + + [JsonPropertyName("time_step")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? TimeStep { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTypeEnumOidc.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTypeEnumOidc.cs new file mode 100644 index 0000000..7ef8b31 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTypeEnumOidc.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionTypeEnumOidc +{ + + [JsonStringEnumMemberName("back_channel")] + BackChannel, + + [JsonStringEnumMemberName("front_channel")] + FrontChannel + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTypeEnumOkta.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTypeEnumOkta.cs new file mode 100644 index 0000000..00109e0 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionTypeEnumOkta.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionTypeEnumOkta +{ + + [JsonStringEnumMemberName("back_channel")] + BackChannel + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUpstreamAdditionalProperties.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUpstreamAdditionalProperties.cs new file mode 100644 index 0000000..b274d7b --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUpstreamAdditionalProperties.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionUpstreamAdditionalProperties +{ + + [JsonPropertyName("alias")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionUpstreamAliasEnum? Alias { get; set; } + + [JsonPropertyName("value")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Value { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUpstreamAliasEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUpstreamAliasEnum.cs new file mode 100644 index 0000000..08e26f9 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUpstreamAliasEnum.cs @@ -0,0 +1,45 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionUpstreamAliasEnum +{ + + [JsonStringEnumMemberName("acr_values")] + AcrValues, + + [JsonStringEnumMemberName("audience")] + Audience, + + [JsonStringEnumMemberName("client_id")] + ClientId, + + [JsonStringEnumMemberName("display")] + Display, + + [JsonStringEnumMemberName("id_token_hint")] + IdTokenHint, + + [JsonStringEnumMemberName("login_hint")] + LoginHint, + + [JsonStringEnumMemberName("max_age")] + MaxAge, + + [JsonStringEnumMemberName("prompt")] + Prompt, + + [JsonStringEnumMemberName("resource")] + Resource, + + [JsonStringEnumMemberName("response_mode")] + ResponseMode, + + [JsonStringEnumMemberName("response_type")] + ResponseType, + + [JsonStringEnumMemberName("ui_locales")] + UiLocales + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUpstreamParam.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUpstreamParam.cs new file mode 100644 index 0000000..67e37cc --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUpstreamParam.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1 +{ + + /// + /// Represents a single upstream parameter mapping forwarded to an identity provider on each authentication request. + /// + public record V2alpha1ConnectionUpstreamParam + { + + /// + /// The name of the parameter as expected by the upstream identity provider. + /// + [JsonPropertyName("alias")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Alias { get; set; } + + /// + /// The name of the parameter as expected by the upstream identity provider. + /// + [JsonPropertyName("value")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Value { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUseridAttributeEnumAzureAd.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUseridAttributeEnumAzureAd.cs new file mode 100644 index 0000000..4691265 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUseridAttributeEnumAzureAd.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionUseridAttributeEnumAzureAd +{ + + [JsonStringEnumMemberName("oid")] + Oid, + + [JsonStringEnumMemberName("sub")] + Sub + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameAllowedTypes.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameAllowedTypes.cs new file mode 100644 index 0000000..fb6b04b --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameAllowedTypes.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionUsernameAllowedTypes +{ + + [JsonPropertyName("email")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Email { get; set; } + + [JsonPropertyName("phone_number")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? PhoneNumber { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameAttribute.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameAttribute.cs new file mode 100644 index 0000000..6a93324 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameAttribute.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionUsernameAttribute +{ + + [JsonPropertyName("identifier")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionAttributeIdentifier? Identifier { get; set; } + + [JsonPropertyName("profile_required")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ProfileRequired { get; set; } + + [JsonPropertyName("signup")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionSignupSchema? Signup { get; set; } + + [JsonPropertyName("validation")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionUsernameValidation? Validation { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameValidation.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameValidation.cs new file mode 100644 index 0000000..802ca57 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameValidation.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionUsernameValidation +{ + + [JsonPropertyName("min_length")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? MinLength { get; set; } + + [JsonPropertyName("max_length")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? MaxLength { get; set; } + + [JsonPropertyName("allowed_types")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionUsernameAllowedTypes? AllowedTypes { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameValidationOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameValidationOptions.cs new file mode 100644 index 0000000..8c57b56 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionUsernameValidationOptions.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionUsernameValidationOptions +{ + + [JsonPropertyName("min")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Min { get; set; } + + [JsonPropertyName("max")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Max { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionValidationOptions.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionValidationOptions.cs new file mode 100644 index 0000000..0ecbba7 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionValidationOptions.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +public record V2alpha1ConnectionValidationOptions +{ + + [JsonPropertyName("username")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V2alpha1ConnectionUsernameValidationOptions? Username { get; set; } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionVerificationMethodEnum.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionVerificationMethodEnum.cs new file mode 100644 index 0000000..25edc30 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionVerificationMethodEnum.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionVerificationMethodEnum +{ + + [JsonStringEnumMemberName("link")] + Link, + + [JsonStringEnumMemberName("otp")] + Otp + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionWaadProtocolEnumAzureAd.cs b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionWaadProtocolEnumAzureAd.cs new file mode 100644 index 0000000..b407bb1 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/Connection/V2alpha1/V2alpha1ConnectionWaadProtocolEnumAzureAd.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum V2alpha1ConnectionWaadProtocolEnumAzureAd +{ + + [JsonStringEnumMemberName("ws_federation")] + WsFederation, + + [JsonStringEnumMemberName("openid_connect")] + OpenidConnect + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerAuthorizationPolicy.cs b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerAuthorizationPolicy.cs new file mode 100644 index 0000000..1787759 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerAuthorizationPolicy.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.ResourceServer.V1 +{ + + public record V1ResourceServerAuthorizationPolicy + { + + [JsonPropertyName("policy_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? PolicyId { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerConf.cs b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerConf.cs index bc3c499..80b6526 100644 --- a/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerConf.cs +++ b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerConf.cs @@ -21,7 +21,7 @@ public record V1ResourceServerConf [JsonPropertyName("scopes")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? Scopes { get; set; } + public V1ResourceServerScope[]? Scopes { get; set; } [JsonPropertyName("signing_alg")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -43,6 +43,14 @@ public record V1ResourceServerConf [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public bool? AllowOfflineAccess { get; set; } + [JsonPropertyName("allow_online_access")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AllowOnlineAccess { get; set; } + + [JsonPropertyName("allow_online_access_with_ephemeral_sessions")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? AllowOnlineAccessWithEphemeralSessions { get; set; } + [JsonPropertyName("skip_consent_for_verifiable_first_party_clients")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public bool? SkipConsentForVerifiableFirstPartyClients { get; set; } @@ -65,7 +73,15 @@ public record V1ResourceServerConf [JsonPropertyName("authorization_details")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public IList? AuthorizationDetails { get; set; } + public V1ResourceServerAuthorizationDetail[]? AuthorizationDetails { get; set; } + + [JsonPropertyName("authorization_policy")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V1ResourceServerAuthorizationPolicy? AuthorizationPolicy { get; set; } + + [JsonPropertyName("subject_type_authorization")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V1ResourceServerSubjectTypeAuthorization? SubjectTypeAuthorization { get; set; } [JsonPropertyName("token_encryption")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] diff --git a/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerMechanism.cs b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerMechanism.cs index ead3362..a5415cc 100644 --- a/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerMechanism.cs +++ b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerMechanism.cs @@ -7,6 +7,9 @@ namespace Alethic.Auth0.Operator.Core.Models.ResourceServer.V1 public enum V1ResourceServerMechanism { + [JsonStringEnumMemberName("dpop")] + Dpop, + [JsonStringEnumMemberName("mtls")] Mtls, diff --git a/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorization.cs b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorization.cs new file mode 100644 index 0000000..15baf02 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorization.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.ResourceServer.V1 +{ + + public record V1ResourceServerSubjectTypeAuthorization + { + + [JsonPropertyName("client")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V1ResourceServerSubjectTypeAuthorizationClient? Client { get; set; } + + [JsonPropertyName("user")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V1ResourceServerSubjectTypeAuthorizationUser? User { get; set; } + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationClient.cs b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationClient.cs new file mode 100644 index 0000000..f1644f3 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationClient.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.ResourceServer.V1 +{ + + public record V1ResourceServerSubjectTypeAuthorizationClient + { + + [JsonPropertyName("policy")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V1ResourceServerSubjectTypeAuthorizationClientPolicy? Policy { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationClientPolicy.cs b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationClientPolicy.cs new file mode 100644 index 0000000..8811ace --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationClientPolicy.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.ResourceServer.V1 +{ + + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V1ResourceServerSubjectTypeAuthorizationClientPolicy + { + + [JsonStringEnumMemberName("deny_all")] + DenyAll, + + [JsonStringEnumMemberName("require_client_grant")] + RequireClientGrant, + + } + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationUser.cs b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationUser.cs new file mode 100644 index 0000000..65e0b26 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationUser.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.ResourceServer.V1 +{ + + public record V1ResourceServerSubjectTypeAuthorizationUser + { + + [JsonPropertyName("policy")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public V1ResourceServerSubjectTypeAuthorizationUserPolicy? Policy { get; set; } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationUserPolicy.cs b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationUserPolicy.cs new file mode 100644 index 0000000..d4ef1e0 --- /dev/null +++ b/src/Alethic.Auth0.Operator.Core/Models/ResourceServer/V1/V1ResourceServerSubjectTypeAuthorizationUserPolicy.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.Core.Models.ResourceServer.V1 +{ + + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum V1ResourceServerSubjectTypeAuthorizationUserPolicy + { + + [JsonStringEnumMemberName("allow_all")] + AllowAll, + + [JsonStringEnumMemberName("deny_all")] + DenyAll, + + [JsonStringEnumMemberName("require_client_grant")] + RequireClientGrant, + + } + +} diff --git a/src/Alethic.Auth0.Operator.Core/Models/Tenant/V1/V1TenantConf.cs b/src/Alethic.Auth0.Operator.Core/Models/Tenant/V1/V1TenantConf.cs index 88f7353..127d6f6 100644 --- a/src/Alethic.Auth0.Operator.Core/Models/Tenant/V1/V1TenantConf.cs +++ b/src/Alethic.Auth0.Operator.Core/Models/Tenant/V1/V1TenantConf.cs @@ -61,11 +61,11 @@ public record V1TenantConf [JsonPropertyName("session_lifetime")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public float? SessionLifetime { get; set; } + public double? SessionLifetime { get; set; } [JsonPropertyName("idle_session_lifetime")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public float? IdleSessionLifetime { get; set; } + public double? IdleSessionLifetime { get; set; } [JsonPropertyName("sandbox_version")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] diff --git a/src/Alethic.Auth0.Operator.Core/Models/Tenant/V2alpha1/V2alpha1TenantSettings.cs b/src/Alethic.Auth0.Operator.Core/Models/Tenant/V2alpha1/V2alpha1TenantSettings.cs index 1c44742..df30175 100644 --- a/src/Alethic.Auth0.Operator.Core/Models/Tenant/V2alpha1/V2alpha1TenantSettings.cs +++ b/src/Alethic.Auth0.Operator.Core/Models/Tenant/V2alpha1/V2alpha1TenantSettings.cs @@ -61,11 +61,11 @@ public record V2alpha1TenantSettings [JsonPropertyName("session_lifetime")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public float? SessionLifetime { get; set; } + public double? SessionLifetime { get; set; } [JsonPropertyName("idle_session_lifetime")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public float? IdleSessionLifetime { get; set; } + public double? IdleSessionLifetime { get; set; } [JsonPropertyName("sandbox_version")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] diff --git a/src/Alethic.Auth0.Operator.Core/Models/V1ConnectionReference.cs b/src/Alethic.Auth0.Operator.Core/Models/V2alpha1ConnectionReference.cs similarity index 88% rename from src/Alethic.Auth0.Operator.Core/Models/V1ConnectionReference.cs rename to src/Alethic.Auth0.Operator.Core/Models/V2alpha1ConnectionReference.cs index b0119be..5c5702e 100644 --- a/src/Alethic.Auth0.Operator.Core/Models/V1ConnectionReference.cs +++ b/src/Alethic.Auth0.Operator.Core/Models/V2alpha1ConnectionReference.cs @@ -1,9 +1,9 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Alethic.Auth0.Operator.Core.Models { - public record V1ConnectionReference + public record V2alpha1ConnectionReference { [JsonPropertyName("namespace")] diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Alethic.Auth0.Operator.ModelGenerator.csproj b/src/Alethic.Auth0.Operator.ModelGenerator/Alethic.Auth0.Operator.ModelGenerator.csproj new file mode 100644 index 0000000..44ddc7f --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Alethic.Auth0.Operator.ModelGenerator.csproj @@ -0,0 +1,15 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + + \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/CommandLine/CommandLineParser.cs b/src/Alethic.Auth0.Operator.ModelGenerator/CommandLine/CommandLineParser.cs new file mode 100644 index 0000000..bdc519f --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/CommandLine/CommandLineParser.cs @@ -0,0 +1,103 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.CommandLine; + +public static class CommandLineParser +{ + public static GeneratorOptions Parse(string[] args) + { + var options = new GeneratorOptions(); + + for (var i = 0; i < args.Length; i++) + { + var arg = args[i]; + switch (arg) + { + case "-h": + case "--help": + case "/?": + options.ShowHelp = true; + break; + case "--write-default-config": + options.WriteDefaultConfiguration = true; + break; + case "--assembly": + options.AssemblyPath = ReadValue(args, ref i, arg); + break; + case "--output": + options.OutputDirectory = ReadValue(args, ref i, arg); + break; + case "--config": + options.ConfigurationPath = ReadValue(args, ref i, arg); + break; + case "--prefix": + options.ClassPrefix = ReadValue(args, ref i, arg); + break; + case "--source-namespace-prefix": + options.SourceNamespacePrefix = ReadValue(args, ref i, arg); + break; + case "--target-namespace-prefix": + options.TargetNamespacePrefix = ReadValue(args, ref i, arg); + break; + case "--overwrite": + options.OverwriteExistingFiles = true; + break; + case "--no-overwrite": + options.OverwriteExistingFiles = false; + break; + default: + throw new ArgumentException($"Unknown argument '{arg}'."); + } + } + + return options; + } + + public static string GetUsage() + { + return string.Join(Environment.NewLine, new[] + { + "Usage:", + " dotnet run --project src/Alethic.Auth0.Operator.ModelGenerator -- --assembly --output [options]", + string.Empty, + "Options:", + " --assembly Path to the source Auth0 assembly.", + " --output Output directory for generated .cs files.", + " --config Optional JSON configuration file.", + " --prefix Optional class name prefix override.", + " --source-namespace-prefix Optional source namespace prefix override.", + " --target-namespace-prefix Optional target namespace prefix override.", + " --overwrite Overwrite existing generated files.", + " --no-overwrite Keep existing generated files.", + " --write-default-config Write a default config file to the config path or current directory.", + " -h|--help Show help.", + }); + } + + public static void ValidateForExecution(GeneratorOptions options) + { + if (options.ShowHelp || options.WriteDefaultConfiguration) + { + return; + } + + if (string.IsNullOrWhiteSpace(options.AssemblyPath)) + { + throw new ArgumentException("The --assembly option is required."); + } + + if (string.IsNullOrWhiteSpace(options.OutputDirectory)) + { + throw new ArgumentException("The --output option is required."); + } + } + + private static string ReadValue(string[] args, ref int index, string optionName) + { + if (index + 1 >= args.Length) + { + throw new ArgumentException($"Missing value for '{optionName}'."); + } + + index++; + return args[index]; + } +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/CommandLine/GeneratorOptions.cs b/src/Alethic.Auth0.Operator.ModelGenerator/CommandLine/GeneratorOptions.cs new file mode 100644 index 0000000..2de89a0 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/CommandLine/GeneratorOptions.cs @@ -0,0 +1,22 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.CommandLine; + +public sealed class GeneratorOptions +{ + public string? AssemblyPath { get; set; } + + public string? OutputDirectory { get; set; } + + public string? ConfigurationPath { get; set; } + + public string? ClassPrefix { get; set; } + + public string? SourceNamespacePrefix { get; set; } + + public string? TargetNamespacePrefix { get; set; } + + public bool? OverwriteExistingFiles { get; set; } + + public bool ShowHelp { get; set; } + + public bool WriteDefaultConfiguration { get; set; } +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/AttributeConfiguration.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/AttributeConfiguration.cs new file mode 100644 index 0000000..f7cfdce --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/AttributeConfiguration.cs @@ -0,0 +1,10 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Configuration; + +public sealed class AttributeConfiguration +{ + public string TypeName { get; set; } = string.Empty; + + public List ConstructorArguments { get; set; } = []; + + public Dictionary NamedArguments { get; set; } = new(StringComparer.Ordinal); +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/GeneratedPropertyConfiguration.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/GeneratedPropertyConfiguration.cs new file mode 100644 index 0000000..1ce4ec2 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/GeneratedPropertyConfiguration.cs @@ -0,0 +1,14 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Configuration; + +public sealed class GeneratedPropertyConfiguration +{ + public string Name { get; set; } = string.Empty; + + public string TypeName { get; set; } = "string?"; + + public string? Summary { get; set; } + + public string? JsonPropertyName { get; set; } + + public List Attributes { get; set; } = []; +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/GeneratorConfiguration.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/GeneratorConfiguration.cs new file mode 100644 index 0000000..a19cf9a --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/GeneratorConfiguration.cs @@ -0,0 +1,110 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Configuration; + +public sealed class GeneratorConfiguration +{ + public string ClassPrefix { get; set; } = "Generated"; + + public string SourceNamespacePrefix { get; set; } = "Auth0.ManagementApi.Models"; + + public string TargetNamespacePrefix { get; set; } = "Alethic.Auth0.Generated.Models"; + + public List RootTypeNames { get; set; } = []; + + public bool FollowReferencedTypes { get; set; } + + public List ResolverSearchDirectories { get; set; } = []; + + public List ResolverAssemblyPaths { get; set; } = []; + + public List SourceTypeNamePrefixes { get; set; } = ["Create", "Update"]; + + public List IncludeNamespaces { get; set; } = ["Auth0.ManagementApi.Models"]; + + public List ExcludeTypeNames { get; set; } = []; + + public List IgnoredPropertyNames { get; set; } = []; + + public Dictionary> IgnoredPropertiesByType { get; set; } = new(StringComparer.Ordinal); + + public List RemovedAttributeTypeNames { get; set; } = + [ + "JsonConverterAttribute", + "Newtonsoft.Json.JsonConverterAttribute", + "IsReadOnlyAttribute", + "System.Runtime.CompilerServices.IsReadOnlyAttribute", + "RequiredAttribute", + "System.ComponentModel.DataAnnotations.RequiredAttribute", + ]; + + public List AddedTypeAttributes { get; set; } = []; + + public List AddedPropertyAttributes { get; set; } = []; + + public List StandardProperties { get; set; } = []; + + public Dictionary NamespaceMappings { get; set; } = new(StringComparer.Ordinal); + + public Dictionary TypeReplacements { get; set; } = new(StringComparer.Ordinal); + + public List TypeNameRewriteRules { get; set; } = []; + + public bool EmitRecords { get; set; } = true; + + public bool UseNamespaceSubdirectories { get; set; } = true; + + public bool OverwriteExistingFiles { get; set; } = true; + + public static GeneratorConfiguration CreateDefault() => new() + { + StandardProperties = + [ + new GeneratedPropertyConfiguration + { + Name = "SourceModelType", + TypeName = "string?", + Summary = "Fully qualified source model type name.", + JsonPropertyName = "sourceModelType", + Attributes = + [ + new AttributeConfiguration + { + TypeName = "JsonIgnore", + NamedArguments = new Dictionary(StringComparer.Ordinal) + { + ["Condition"] = "JsonIgnoreCondition.WhenWritingNull", + }, + }, + ], + }, + ], + }; + + public GeneratorConfiguration ApplyOverrides(CommandLine.GeneratorOptions options) + { + return new GeneratorConfiguration + { + ClassPrefix = string.IsNullOrWhiteSpace(options.ClassPrefix) ? ClassPrefix : options.ClassPrefix, + SourceNamespacePrefix = string.IsNullOrWhiteSpace(options.SourceNamespacePrefix) ? SourceNamespacePrefix : options.SourceNamespacePrefix, + TargetNamespacePrefix = string.IsNullOrWhiteSpace(options.TargetNamespacePrefix) ? TargetNamespacePrefix : options.TargetNamespacePrefix, + RootTypeNames = [.. RootTypeNames], + FollowReferencedTypes = FollowReferencedTypes, + ResolverSearchDirectories = [.. ResolverSearchDirectories], + ResolverAssemblyPaths = [.. ResolverAssemblyPaths], + SourceTypeNamePrefixes = [.. SourceTypeNamePrefixes], + IncludeNamespaces = [.. IncludeNamespaces], + ExcludeTypeNames = [.. ExcludeTypeNames], + IgnoredPropertyNames = [.. IgnoredPropertyNames], + IgnoredPropertiesByType = new Dictionary>(IgnoredPropertiesByType, StringComparer.Ordinal), + RemovedAttributeTypeNames = [.. RemovedAttributeTypeNames], + AddedTypeAttributes = [.. AddedTypeAttributes], + AddedPropertyAttributes = [.. AddedPropertyAttributes], + StandardProperties = [.. StandardProperties], + NamespaceMappings = new Dictionary(NamespaceMappings, StringComparer.Ordinal), + TypeReplacements = new Dictionary(TypeReplacements, StringComparer.Ordinal), + TypeNameRewriteRules = [.. TypeNameRewriteRules], + EmitRecords = EmitRecords, + UseNamespaceSubdirectories = UseNamespaceSubdirectories, + OverwriteExistingFiles = options.OverwriteExistingFiles ?? OverwriteExistingFiles, + }; + } +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/GeneratorConfigurationLoader.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/GeneratorConfigurationLoader.cs new file mode 100644 index 0000000..fbb8543 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/GeneratorConfigurationLoader.cs @@ -0,0 +1,39 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Alethic.Auth0.Operator.ModelGenerator.Configuration; + +public static class GeneratorConfigurationLoader +{ + private static readonly JsonSerializerOptions SerializerOptions = new() + { + PropertyNameCaseInsensitive = true, + ReadCommentHandling = JsonCommentHandling.Skip, + AllowTrailingCommas = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + WriteIndented = true, + }; + + public static GeneratorConfiguration Load(string? path) + { + if (string.IsNullOrWhiteSpace(path)) + { + return GeneratorConfiguration.CreateDefault(); + } + + var fullPath = Path.GetFullPath(path); + if (!File.Exists(fullPath)) + { + throw new FileNotFoundException($"Configuration file '{fullPath}' was not found.", fullPath); + } + + var json = File.ReadAllText(fullPath); + return JsonSerializer.Deserialize(json, SerializerOptions) + ?? GeneratorConfiguration.CreateDefault(); + } + + public static string Serialize(GeneratorConfiguration configuration) + { + return JsonSerializer.Serialize(configuration, SerializerOptions); + } +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/TypeNameRewriteRuleConfiguration.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/TypeNameRewriteRuleConfiguration.cs new file mode 100644 index 0000000..9b287b1 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Configuration/TypeNameRewriteRuleConfiguration.cs @@ -0,0 +1,8 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Configuration; + +public sealed class TypeNameRewriteRuleConfiguration +{ + public required string Pattern { get; set; } + + public required string Replacement { get; set; } +} diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/AssemblyTypeDiscoverer.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/AssemblyTypeDiscoverer.cs new file mode 100644 index 0000000..6134ad7 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/AssemblyTypeDiscoverer.cs @@ -0,0 +1,393 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +using Alethic.Auth0.Operator.ModelGenerator.Configuration; + +using Microsoft.CodeAnalysis; + +namespace Alethic.Auth0.Operator.ModelGenerator.Discovery; + +public sealed class AssemblyTypeDiscoverer +{ + private static readonly NullabilityInfoContext NullabilityContext = new(); + + public DiscoveryResult Discover(string assemblyPath, GeneratorConfiguration configuration) + { + var fullAssemblyPath = Path.GetFullPath(assemblyPath); + if (!File.Exists(fullAssemblyPath)) + { + throw new FileNotFoundException($"Assembly '{fullAssemblyPath}' was not found.", fullAssemblyPath); + } + + var resolver = new PathAssemblyResolver(GetResolverPaths(fullAssemblyPath, configuration)); + using var metadataLoadContext = new MetadataLoadContext(resolver); + var assembly = metadataLoadContext.LoadFromAssemblyPath(fullAssemblyPath); + + var candidateTypes = assembly.DefinedTypes + .Select(typeInfo => typeInfo.AsType()) + .Where(type => IsCandidate(type, configuration)) + .ToDictionary(type => type.FullName ?? type.Name, StringComparer.Ordinal); + + var selectedTypes = SelectTypes(candidateTypes, configuration); + + var discoveredTypes = selectedTypes + .Select(MapType) + .OrderBy(type => type.Namespace, StringComparer.Ordinal) + .ThenBy(type => type.Name, StringComparer.Ordinal) + .ToList(); + + return new DiscoveryResult + { + AssemblyPath = fullAssemblyPath, + AssemblyName = assembly.GetName().Name ?? Path.GetFileNameWithoutExtension(fullAssemblyPath), + Types = discoveredTypes, + }; + } + + private static IReadOnlyCollection SelectTypes(IReadOnlyDictionary candidateTypes, GeneratorConfiguration configuration) + { + if (configuration.RootTypeNames.Count == 0) + { + return [.. candidateTypes.Values]; + } + + var queue = new Queue(candidateTypes.Values.Where(type => MatchesRootType(type, configuration.RootTypeNames))); + var selectedTypes = new Dictionary(StringComparer.Ordinal); + while (queue.Count > 0) + { + var current = queue.Dequeue(); + var currentKey = current.FullName ?? current.Name; + if (!selectedTypes.TryAdd(currentKey, current)) + { + continue; + } + + if (!configuration.FollowReferencedTypes) + { + continue; + } + + foreach (var referencedType in GetReferencedTypes(current, candidateTypes)) + { + queue.Enqueue(referencedType); + } + } + + return [.. selectedTypes.Values]; + } + + private static IEnumerable GetResolverPaths(string assemblyPath, GeneratorConfiguration configuration) + { + var assemblyDirectory = Path.GetDirectoryName(assemblyPath)!; + + return Directory.EnumerateFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll") + .Concat(Directory.EnumerateFiles(assemblyDirectory, "*.dll")) + .Concat(Directory.EnumerateFiles(assemblyDirectory, "*.exe")) + .Concat(configuration.ResolverSearchDirectories.SelectMany(EnumerateResolverFiles)) + .Concat(configuration.ResolverAssemblyPaths.Where(File.Exists).Select(Path.GetFullPath)) + .Append(assemblyPath) + .Distinct(StringComparer.OrdinalIgnoreCase); + } + + private static IEnumerable EnumerateResolverFiles(string directory) + { + var fullDirectory = Path.GetFullPath(directory); + if (!Directory.Exists(fullDirectory)) + { + return []; + } + + return Directory.EnumerateFiles(fullDirectory, "*.dll", SearchOption.AllDirectories) + .Concat(Directory.EnumerateFiles(fullDirectory, "*.exe", SearchOption.AllDirectories)); + } + + private static bool IsCandidate(Type type, GeneratorConfiguration configuration) + { + if (!type.IsPublic || type.IsNested) + { + return false; + } + + if (!type.IsClass && !IsEnumLikeValueType(type)) + { + return false; + } + + if (string.IsNullOrWhiteSpace(type.Namespace)) + { + return false; + } + + var fullName = type.FullName ?? type.Name; + if (configuration.ExcludeTypeNames.Contains(type.Name, StringComparer.Ordinal) + || configuration.ExcludeTypeNames.Contains(fullName, StringComparer.Ordinal)) + { + return false; + } + + if (!string.IsNullOrWhiteSpace(configuration.SourceNamespacePrefix) + && !type.Namespace.StartsWith(configuration.SourceNamespacePrefix, StringComparison.Ordinal)) + { + return false; + } + + if (configuration.IncludeNamespaces.Count > 0 + && !configuration.IncludeNamespaces.Any(item => type.Namespace.StartsWith(item, StringComparison.Ordinal))) + { + return false; + } + + if (configuration.SourceTypeNamePrefixes.Count > 0 + && !configuration.SourceTypeNamePrefixes.Any(prefix => type.Name.StartsWith(prefix, StringComparison.Ordinal))) + { + return false; + } + + return true; + } + + private static bool MatchesRootType(Type type, IReadOnlyCollection rootTypeNames) + { + var fullName = type.FullName ?? type.Name; + foreach (var rootTypeName in rootTypeNames) + { + if (rootTypeName.EndsWith('*')) + { + var prefix = rootTypeName[..^1]; + if (type.Name.StartsWith(prefix, StringComparison.Ordinal) + || fullName.StartsWith(prefix, StringComparison.Ordinal)) + { + return true; + } + + continue; + } + + if (string.Equals(type.Name, rootTypeName, StringComparison.Ordinal) + || string.Equals(fullName, rootTypeName, StringComparison.Ordinal)) + { + return true; + } + } + + return false; + } + + private static IEnumerable GetReferencedTypes(Type type, IReadOnlyDictionary candidateTypes) + { + foreach (var property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) + { + foreach (var referencedType in FlattenReferencedTypes(property.PropertyType)) + { + var key = referencedType.FullName ?? referencedType.Name; + if (candidateTypes.TryGetValue(key, out var candidateType)) + { + yield return candidateType; + } + } + } + } + + private static IEnumerable FlattenReferencedTypes(Type type) + { + if (type.IsByRef) + { + foreach (var referencedType in FlattenReferencedTypes(type.GetElementType()!)) + { + yield return referencedType; + } + + yield break; + } + + if (type.IsArray) + { + foreach (var referencedType in FlattenReferencedTypes(type.GetElementType()!)) + { + yield return referencedType; + } + + yield break; + } + + var nullableType = Nullable.GetUnderlyingType(type); + if (nullableType is not null) + { + foreach (var referencedType in FlattenReferencedTypes(nullableType)) + { + yield return referencedType; + } + + yield break; + } + + if (type.IsGenericType) + { + var genericTypeDefinition = type.GetGenericTypeDefinition(); + if (!string.Equals(genericTypeDefinition.FullName, "Auth0.ManagementApi.Core.Optional`1", StringComparison.Ordinal)) + { + yield return genericTypeDefinition; + } + + foreach (var genericArgument in type.GetGenericArguments()) + { + foreach (var referencedType in FlattenReferencedTypes(genericArgument)) + { + yield return referencedType; + } + } + + yield break; + } + + if ((type.IsClass || IsEnumLikeValueType(type)) && !string.IsNullOrWhiteSpace(type.Namespace)) + { + yield return type; + } + } + + private static bool IsEnumLikeValueType(Type type) + { + return type.IsValueType + && !type.IsPrimitive + && !type.IsGenericType + && !string.IsNullOrWhiteSpace(type.Namespace) + && type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Length > 0; + } + + private static string ConvertNameToSnakeCase(string name) + { + if (string.IsNullOrEmpty(name)) + { + return name; + } + + var builder = new System.Text.StringBuilder(name.Length + 8); + for (var i = 0; i < name.Length; i++) + { + var current = name[i]; + if (char.IsUpper(current) && i > 0 && (char.IsLower(name[i - 1]) || (i + 1 < name.Length && char.IsLower(name[i + 1])))) + { + builder.Append('_'); + } + + builder.Append(char.ToLowerInvariant(current)); + } + + return builder.ToString(); + } + + private static DiscoveredType MapType(Type type) + { + var isEnumLike = IsEnumLikeValueType(type); + var enumMembers = isEnumLike + ? GetEnumLikeMembers(type) + : []; + + return new DiscoveredType + { + Name = type.Name, + Namespace = type.Namespace!, + FullName = type.FullName ?? type.Name, + IsEnumLike = isEnumLike, + Attributes = [.. CustomAttributeData.GetCustomAttributes(type).Select(MapAttribute)], + Properties = isEnumLike + ? [] + : [.. type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly) + .Where(property => property.GetMethod?.IsPublic == true) + .OrderBy(property => property.MetadataToken) + .Select(MapProperty)], + EnumMembers = enumMembers, + }; + } + + private static List GetEnumLikeMembers(Type type) + { + var valuesType = type.GetNestedType("Values", BindingFlags.Public | BindingFlags.NonPublic); + if (valuesType is null) + { + return [.. type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly) + .OrderBy(field => field.MetadataToken) + .Select(field => new DiscoveredEnumMember + { + Name = field.Name, + SerializedName = ConvertNameToSnakeCase(field.Name), + })]; + } + + return [.. valuesType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly) + .Where(field => field.IsLiteral || field.IsStatic) + .OrderBy(field => field.MetadataToken) + .Select(MapEnumLikeMember) + .OfType()]; + } + + private static DiscoveredEnumMember? MapEnumLikeMember(FieldInfo field) + { + var serializedName = GetEnumLikeSerializedName(field); + if (string.IsNullOrWhiteSpace(serializedName)) + { + return null; + } + + return new DiscoveredEnumMember + { + Name = field.Name, + SerializedName = serializedName, + }; + } + + private static string? GetEnumLikeSerializedName(FieldInfo field) + { + if (field.FieldType == typeof(string)) + { + if (field.IsLiteral) + { + return field.GetRawConstantValue() as string; + } + + try + { + return field.GetValue(null) as string; + } + catch + { + return null; + } + } + + return ConvertNameToSnakeCase(field.Name); + } + + private static DiscoveredProperty MapProperty(PropertyInfo property) + { + var nullability = NullabilityContext.Create(property); + + return new DiscoveredProperty + { + Name = property.Name, + Type = DiscoveredTypeReference.FromType(property.PropertyType, nullability), + HasPublicSetter = property.SetMethod?.IsPublic == true, + Attributes = [.. CustomAttributeData.GetCustomAttributes(property).Select(MapAttribute)], + }; + } + + private static DiscoveredAttribute MapAttribute(CustomAttributeData attribute) + { + var attributeType = attribute.AttributeType; + var shortTypeName = attributeType.Name.EndsWith("Attribute", StringComparison.Ordinal) + ? attributeType.Name[..^9] + : attributeType.Name; + + return new DiscoveredAttribute + { + TypeName = attributeType.FullName ?? attributeType.Name, + ShortTypeName = shortTypeName, + ConstructorArguments = [.. attribute.ConstructorArguments.Select(AttributeValueFormatter.Format)], + NamedArguments = attribute.NamedArguments.ToDictionary( + argument => argument.MemberName, + argument => AttributeValueFormatter.Format(argument.TypedValue), + StringComparer.Ordinal), + }; + } +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/AttributeValueFormatter.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/AttributeValueFormatter.cs new file mode 100644 index 0000000..7418ebf --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/AttributeValueFormatter.cs @@ -0,0 +1,83 @@ +using System.Globalization; +using System.Reflection; + +namespace Alethic.Auth0.Operator.ModelGenerator.Discovery; + +internal static class AttributeValueFormatter +{ + public static string Format(CustomAttributeTypedArgument argument) + { + if (argument.Value is null) + { + return "null"; + } + + var argumentType = argument.ArgumentType; + var argumentTypeFullName = argumentType.FullName; + if (string.Equals(argumentTypeFullName, typeof(string).FullName, StringComparison.Ordinal)) + { + return "\"" + ((string)argument.Value).Replace("\\", "\\\\", StringComparison.Ordinal).Replace("\"", "\\\"", StringComparison.Ordinal) + "\""; + } + + if (string.Equals(argumentTypeFullName, typeof(char).FullName, StringComparison.Ordinal)) + { + return "'" + (((char)argument.Value).ToString()).Replace("\\", "\\\\", StringComparison.Ordinal).Replace("'", "\\'", StringComparison.Ordinal) + "'"; + } + + if (string.Equals(argumentTypeFullName, typeof(bool).FullName, StringComparison.Ordinal)) + { + return ((bool)argument.Value) ? "true" : "false"; + } + + if (string.Equals(argumentTypeFullName, typeof(float).FullName, StringComparison.Ordinal)) + { + return ((float)argument.Value).ToString(CultureInfo.InvariantCulture) + "F"; + } + + if (string.Equals(argumentTypeFullName, typeof(double).FullName, StringComparison.Ordinal)) + { + return ((double)argument.Value).ToString("R", CultureInfo.InvariantCulture) + "D"; + } + + if (string.Equals(argumentTypeFullName, typeof(decimal).FullName, StringComparison.Ordinal)) + { + return ((decimal)argument.Value).ToString(CultureInfo.InvariantCulture) + "M"; + } + + if (string.Equals(argumentTypeFullName, typeof(long).FullName, StringComparison.Ordinal)) + { + return ((long)argument.Value).ToString(CultureInfo.InvariantCulture) + "L"; + } + + if (string.Equals(argumentTypeFullName, typeof(uint).FullName, StringComparison.Ordinal)) + { + return ((uint)argument.Value).ToString(CultureInfo.InvariantCulture) + "U"; + } + + if (string.Equals(argumentTypeFullName, typeof(ulong).FullName, StringComparison.Ordinal)) + { + return ((ulong)argument.Value).ToString(CultureInfo.InvariantCulture) + "UL"; + } + + if (string.Equals(argumentTypeFullName, typeof(Type).FullName, StringComparison.Ordinal)) + { + return $"typeof({((Type)argument.Value).FullName})"; + } + + if (argumentType.IsEnum) + { + var enumName = Enum.GetName(argumentType, argument.Value); + return enumName is null + ? Convert.ToString(argument.Value, CultureInfo.InvariantCulture) ?? "0" + : $"{argumentType.FullName}.{enumName}"; + } + + if (argument.Value is IReadOnlyCollection collection) + { + var values = string.Join(", ", collection.Select(Format)); + return $"new[] {{ {values} }}"; + } + + return Convert.ToString(argument.Value, CultureInfo.InvariantCulture) ?? "null"; + } +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredAttribute.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredAttribute.cs new file mode 100644 index 0000000..43a21e6 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredAttribute.cs @@ -0,0 +1,12 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Discovery; + +public sealed class DiscoveredAttribute +{ + public required string TypeName { get; init; } + + public required string ShortTypeName { get; init; } + + public List ConstructorArguments { get; init; } = []; + + public Dictionary NamedArguments { get; init; } = new(StringComparer.Ordinal); +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredEnumMember.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredEnumMember.cs new file mode 100644 index 0000000..5df0f76 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredEnumMember.cs @@ -0,0 +1,8 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Discovery; + +public sealed class DiscoveredEnumMember +{ + public required string Name { get; init; } + + public required string SerializedName { get; init; } +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredProperty.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredProperty.cs new file mode 100644 index 0000000..efa9150 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredProperty.cs @@ -0,0 +1,12 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Discovery; + +public sealed class DiscoveredProperty +{ + public required string Name { get; init; } + + public required DiscoveredTypeReference Type { get; init; } + + public bool HasPublicSetter { get; init; } + + public List Attributes { get; init; } = []; +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredType.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredType.cs new file mode 100644 index 0000000..79251e3 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredType.cs @@ -0,0 +1,18 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Discovery; + +public sealed class DiscoveredType +{ + public required string Name { get; init; } + + public required string Namespace { get; init; } + + public required string FullName { get; init; } + + public bool IsEnumLike { get; init; } + + public List Attributes { get; init; } = []; + + public List Properties { get; init; } = []; + + public List EnumMembers { get; init; } = []; +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredTypeReference.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredTypeReference.cs new file mode 100644 index 0000000..1af16f3 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveredTypeReference.cs @@ -0,0 +1,178 @@ +using System.Reflection; + +namespace Alethic.Auth0.Operator.ModelGenerator.Discovery; + +public sealed class DiscoveredTypeReference +{ + public const string OptionalGenericTypeFullName = "Auth0.ManagementApi.Core.Optional`1"; + + public required string Name { get; init; } + + public string Namespace { get; init; } = string.Empty; + + public string? FullName { get; init; } + + public string? Alias { get; init; } + + public bool IsReferenceType { get; init; } + + public bool IsNullableReferenceType { get; init; } + + public bool IsValueType { get; init; } + + public bool IsNullableValueType { get; init; } + + public bool IsOptionalWrapper { get; init; } + + public bool IsArray { get; init; } + + public int ArrayRank { get; init; } + + public DiscoveredTypeReference? ElementType { get; init; } + + public List GenericArguments { get; init; } = []; + + public static DiscoveredTypeReference FromType(Type type) + { + return FromType(type, null); + } + + public static DiscoveredTypeReference FromType(Type type, NullabilityInfo? nullability) + { + if (type.IsByRef) + { + return FromType(type.GetElementType()!, nullability?.ElementType); + } + + if (type.IsArray) + { + return new DiscoveredTypeReference + { + Name = type.Name, + Namespace = type.Namespace ?? string.Empty, + FullName = type.FullName, + Alias = null, + IsReferenceType = true, + IsNullableReferenceType = false, + IsValueType = false, + IsNullableValueType = false, + IsOptionalWrapper = false, + IsArray = true, + ArrayRank = type.GetArrayRank(), + ElementType = FromType(type.GetElementType()!, nullability?.ElementType), + }; + } + + var underlyingNullableType = Nullable.GetUnderlyingType(type); + if (underlyingNullableType is not null) + { + var nullableTypeReference = FromType(underlyingNullableType, nullability?.GenericTypeArguments.FirstOrDefault()); + return new DiscoveredTypeReference + { + Name = nullableTypeReference.Name, + Namespace = nullableTypeReference.Namespace, + FullName = nullableTypeReference.FullName, + Alias = nullableTypeReference.Alias, + IsReferenceType = nullableTypeReference.IsReferenceType, + IsNullableReferenceType = nullableTypeReference.IsNullableReferenceType, + IsValueType = nullableTypeReference.IsValueType, + IsNullableValueType = true, + IsOptionalWrapper = nullableTypeReference.IsOptionalWrapper, + IsArray = nullableTypeReference.IsArray, + ArrayRank = nullableTypeReference.ArrayRank, + ElementType = nullableTypeReference.ElementType, + GenericArguments = [.. nullableTypeReference.GenericArguments], + }; + } + + if (type.IsGenericParameter) + { + return new DiscoveredTypeReference + { + Name = type.Name, + Namespace = string.Empty, + FullName = type.Name, + Alias = null, + IsReferenceType = false, + IsNullableReferenceType = false, + IsValueType = false, + IsNullableValueType = false, + IsOptionalWrapper = false, + }; + } + + if (type.IsGenericType && string.Equals(type.GetGenericTypeDefinition().FullName, OptionalGenericTypeFullName, StringComparison.Ordinal)) + { + var optionalValueType = FromType(type.GetGenericArguments()[0], nullability?.GenericTypeArguments.FirstOrDefault()); + return new DiscoveredTypeReference + { + Name = optionalValueType.Name, + Namespace = optionalValueType.Namespace, + FullName = optionalValueType.FullName, + Alias = optionalValueType.Alias, + IsReferenceType = optionalValueType.IsReferenceType, + IsNullableReferenceType = optionalValueType.IsReferenceType, + IsValueType = optionalValueType.IsValueType, + IsNullableValueType = optionalValueType.IsValueType || optionalValueType.IsNullableValueType, + IsOptionalWrapper = true, + IsArray = optionalValueType.IsArray, + ArrayRank = optionalValueType.ArrayRank, + ElementType = optionalValueType.ElementType, + GenericArguments = [.. optionalValueType.GenericArguments], + }; + } + + var nullabilityGenericArguments = nullability?.GenericTypeArguments?.ToArray() ?? []; + var genericArguments = type.IsGenericType + ? type.GetGenericArguments().Select((argument, index) => + FromType(argument, index < nullabilityGenericArguments.Length + ? nullabilityGenericArguments[index] + : null)).ToList() + : []; + + return new DiscoveredTypeReference + { + Name = GetSimpleTypeName(type), + Namespace = type.Namespace ?? string.Empty, + FullName = type.FullName, + Alias = TypeAliasMap.TryGetValue(type.FullName ?? string.Empty, out var alias) ? alias : null, + IsReferenceType = !type.IsValueType, + IsNullableReferenceType = !type.IsValueType && nullability?.ReadState == NullabilityState.Nullable, + IsValueType = type.IsValueType, + IsNullableValueType = false, + IsOptionalWrapper = false, + IsArray = false, + ArrayRank = 0, + ElementType = null, + GenericArguments = genericArguments, + }; + } + + private static string GetSimpleTypeName(Type type) + { + var name = type.Name; + var tickIndex = name.IndexOf('`'); + return tickIndex >= 0 ? name[..tickIndex] : name; + } + + private static readonly Dictionary TypeAliasMap = new(StringComparer.Ordinal) + { + [typeof(bool).FullName!] = "bool", + [typeof(byte).FullName!] = "byte", + [typeof(char).FullName!] = "char", + [typeof(decimal).FullName!] = "decimal", + [typeof(double).FullName!] = "double", + [typeof(float).FullName!] = "float", + [typeof(int).FullName!] = "int", + [typeof(long).FullName!] = "long", + [typeof(object).FullName!] = "object", + [typeof(sbyte).FullName!] = "sbyte", + [typeof(short).FullName!] = "short", + [typeof(string).FullName!] = "string", + [typeof(uint).FullName!] = "uint", + [typeof(ulong).FullName!] = "ulong", + [typeof(ushort).FullName!] = "ushort", + [typeof(void).FullName!] = "void", + }; + +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveryResult.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveryResult.cs new file mode 100644 index 0000000..9ddb807 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Discovery/DiscoveryResult.cs @@ -0,0 +1,10 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Discovery; + +public sealed class DiscoveryResult +{ + public required string AssemblyPath { get; init; } + + public required string AssemblyName { get; init; } + + public List Types { get; init; } = []; +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Generation/RoslynCodeWriter.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Generation/RoslynCodeWriter.cs new file mode 100644 index 0000000..27d19a0 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Generation/RoslynCodeWriter.cs @@ -0,0 +1,244 @@ +using Alethic.Auth0.Operator.ModelGenerator.Configuration; +using Alethic.Auth0.Operator.ModelGenerator.Discovery; +using Alethic.Auth0.Operator.ModelGenerator.Transformation; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; + +namespace Alethic.Auth0.Operator.ModelGenerator.Generation; + +public sealed class RoslynCodeWriter +{ + public GenerationResult WriteFiles(IEnumerable generatedTypes, string outputDirectory, GeneratorConfiguration configuration) + { + var fullOutputDirectory = Path.GetFullPath(outputDirectory); + Directory.CreateDirectory(fullOutputDirectory); + + var generatedFiles = new List(); + foreach (var generatedType in generatedTypes) + { + var relativePath = configuration.UseNamespaceSubdirectories + ? Path.Combine(generatedType.Namespace.Replace('.', Path.DirectorySeparatorChar), generatedType.Name + ".cs") + : generatedType.Name + ".cs"; + var filePath = Path.Combine(fullOutputDirectory, relativePath); + Directory.CreateDirectory(Path.GetDirectoryName(filePath)!); + + if (!configuration.OverwriteExistingFiles && File.Exists(filePath)) + { + continue; + } + + var compilationUnit = CompilationUnit() + .WithUsings(List(generatedType.UsingDirectives.Select(@namespace => UsingDirective(ParseName(@namespace))))) + .WithMembers(List( + [ + FileScopedNamespaceDeclaration(ParseName(generatedType.Namespace)) + .WithMembers(List([CreateTypeDeclaration(generatedType, configuration)])), + ])) + .NormalizeWhitespace(); + + var generatedSource = FormatGeneratedSource(compilationUnit.ToFullString(), generatedType, configuration) + Environment.NewLine; + File.WriteAllText(filePath, generatedSource); + generatedFiles.Add(filePath); + } + + return new GenerationResult + { + OutputDirectory = fullOutputDirectory, + GeneratedFiles = generatedFiles, + }; + } + + private static string FormatGeneratedSource(string source, GeneratedType generatedType, GeneratorConfiguration configuration) + { + var lineEnding = Environment.NewLine; + var namespaceLine = $"namespace {generatedType.Namespace};{lineEnding}"; + source = source.Replace(namespaceLine, namespaceLine + lineEnding, StringComparison.Ordinal); + + if (generatedType.IsEnumLike) + { + var enumOpening = $"public enum {generatedType.Name}{lineEnding}{{{lineEnding}"; + source = source.Replace(enumOpening, enumOpening + lineEnding, StringComparison.Ordinal); + + foreach (var member in generatedType.EnumMembers.Take(Math.Max(0, generatedType.EnumMembers.Count - 1))) + { + var memberLine = $" {member.Name},{lineEnding}"; + source = source.Replace(memberLine, memberLine + lineEnding, StringComparison.Ordinal); + } + + var enumClosingBrace = source.LastIndexOf(lineEnding + "}", StringComparison.Ordinal); + if (enumClosingBrace >= 0) + { + source = source.Insert(enumClosingBrace, lineEnding); + } + + return source; + } + + var typeKeyword = configuration.EmitRecords ? "record" : "class"; + var typeOpening = $"public {typeKeyword} {generatedType.Name}{lineEnding}{{{lineEnding}"; + source = source.Replace(typeOpening, typeOpening + lineEnding, StringComparison.Ordinal); + + var lastClosingBrace = source.LastIndexOf(lineEnding + "}", StringComparison.Ordinal); + if (lastClosingBrace >= 0) + { + source = source.Insert(lastClosingBrace, lineEnding); + } + + return source; + } + + private static MemberDeclarationSyntax CreateTypeDeclaration(GeneratedType generatedType, GeneratorConfiguration configuration) + { + if (generatedType.IsEnumLike) + { + return CreateEnumDeclaration(generatedType); + } + + var members = generatedType.Properties.Select(CreatePropertyDeclaration).ToArray(); + if (members.Length > 0) + { + members[0] = members[0].WithLeadingTrivia(members[0].GetLeadingTrivia().Insert(0, ElasticCarriageReturnLineFeed)); + members[^1] = members[^1].WithTrailingTrivia(members[^1].GetTrailingTrivia().Add(ElasticCarriageReturnLineFeed)); + } + + TypeDeclarationSyntax declaration; + if (configuration.EmitRecords) + { + declaration = RecordDeclaration( + kind: SyntaxKind.RecordDeclaration, + attributeLists: default, + modifiers: TokenList(Token(SyntaxKind.PublicKeyword)), + keyword: Token(SyntaxKind.RecordKeyword), + classOrStructKeyword: default, + identifier: Identifier(generatedType.Name), + typeParameterList: null, + parameterList: null, + baseList: null, + constraintClauses: default, + openBraceToken: Token(SyntaxKind.OpenBraceToken), + members: List(members), + closeBraceToken: Token(SyntaxKind.CloseBraceToken), + semicolonToken: default) + .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))); + } + else + { + declaration = ClassDeclaration(generatedType.Name) + .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))) + .WithMembers(List(members)); + } + + if (generatedType.Attributes.Count > 0) + { + declaration = declaration.WithAttributeLists(List(generatedType.Attributes.Select(CreateAttributeList))); + } + + return declaration; + } + + private static MemberDeclarationSyntax CreateEnumDeclaration(GeneratedType generatedType) + { + var declaration = EnumDeclaration(generatedType.Name) + .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))) + .WithMembers(SeparatedList(generatedType.EnumMembers.Select(CreateEnumMemberDeclaration))); + + return declaration.WithAttributeLists(List(new[] + { + AttributeList(SingletonSeparatedList(Attribute(IdentifierName("JsonConverter")) + .WithArgumentList(AttributeArgumentList(SingletonSeparatedList(AttributeArgument(ParseExpression("typeof(JsonStringEnumConverter)"))))))), + })); + } + + private static EnumMemberDeclarationSyntax CreateEnumMemberDeclaration((string Name, string SerializedName) member) + { + return EnumMemberDeclaration(member.Name) + .WithAttributeLists(List(new[] + { + AttributeList(SingletonSeparatedList(Attribute(IdentifierName("JsonStringEnumMemberName")) + .WithArgumentList(AttributeArgumentList(SingletonSeparatedList(AttributeArgument(ParseExpression("\"" + member.SerializedName + "\""))))))), + })); + } + + private static MemberDeclarationSyntax CreatePropertyDeclaration(GeneratedProperty property) + { + var accessors = property.HasSetter + ? new[] + { + AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(Token(SyntaxKind.SemicolonToken)), + AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(Token(SyntaxKind.SemicolonToken)), + } + : new[] + { + AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(Token(SyntaxKind.SemicolonToken)), + }; + + var declaration = PropertyDeclaration(ParseTypeName(RenderType(property.Type)), property.Name) + .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))) + .WithAccessorList(AccessorList(List(accessors))); + + if (property.Attributes.Count > 0) + { + declaration = declaration.WithAttributeLists(List(property.Attributes.Select(CreateAttributeList))); + } + + if (!string.IsNullOrWhiteSpace(property.Summary)) + { + declaration = declaration.WithLeadingTrivia(TriviaList(CreateSummaryTrivia(property.Summary!))); + } + + return declaration; + } + + private static AttributeListSyntax CreateAttributeList(GeneratedAttribute attribute) + { + var arguments = new List(); + arguments.AddRange(attribute.ConstructorArguments.Select(argument => AttributeArgument(ParseExpression(argument)))); + arguments.AddRange(attribute.NamedArguments.Select(argument => AttributeArgument(ParseExpression(argument.Value)) + .WithNameEquals(NameEquals(IdentifierName(argument.Key))))); + + var attributeName = attribute.TypeName.EndsWith("Attribute", StringComparison.Ordinal) + ? attribute.TypeName[..^9] + : attribute.TypeName; + + return AttributeList(SingletonSeparatedList(Attribute(ParseName(attributeName)) + .WithArgumentList(arguments.Count == 0 ? null : AttributeArgumentList(SeparatedList(arguments))))); + } + + private static IEnumerable CreateSummaryTrivia(string summary) + { + yield return Comment("/// "); + yield return ElasticCarriageReturnLineFeed; + yield return Comment($"/// {summary}"); + yield return ElasticCarriageReturnLineFeed; + yield return Comment("/// "); + yield return ElasticCarriageReturnLineFeed; + } + + private static string RenderType(DiscoveredTypeReference type) + { + if (type.IsArray && type.ElementType is not null) + { + var arrayType = RenderType(type.ElementType) + string.Concat(Enumerable.Repeat("[]", Math.Max(1, type.ArrayRank))); + return type.IsNullableReferenceType + ? arrayType + "?" + : arrayType; + } + + var baseType = type.Alias ?? type.Name; + if (type.GenericArguments.Count > 0) + { + baseType += "<" + string.Join(", ", type.GenericArguments.Select(RenderType)) + ">"; + } + + if (type.IsNullableValueType || type.IsNullableReferenceType) + { + return baseType + "?"; + } + + return baseType; + } +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Program.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Program.cs new file mode 100644 index 0000000..42a3fe5 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Program.cs @@ -0,0 +1,66 @@ +using Alethic.Auth0.Operator.ModelGenerator.CommandLine; +using Alethic.Auth0.Operator.ModelGenerator.Configuration; +using Alethic.Auth0.Operator.ModelGenerator.Discovery; +using Alethic.Auth0.Operator.ModelGenerator.Generation; +using Alethic.Auth0.Operator.ModelGenerator.Transformation; + +namespace Alethic.Auth0.Operator.ModelGenerator; + +internal static class Program +{ + private static int Main(string[] args) + { + try + { + var options = CommandLineParser.Parse(args); + if (options.ShowHelp) + { + Console.WriteLine(CommandLineParser.GetUsage()); + return 0; + } + + var configuration = GeneratorConfigurationLoader.Load(options.ConfigurationPath) + .ApplyOverrides(options); + + if (options.WriteDefaultConfiguration) + { + var path = GetDefaultConfigurationOutputPath(options.ConfigurationPath); + Directory.CreateDirectory(Path.GetDirectoryName(path)!); + File.WriteAllText(path, GeneratorConfigurationLoader.Serialize(configuration)); + Console.WriteLine($"Wrote default configuration to '{path}'."); + return 0; + } + + CommandLineParser.ValidateForExecution(options); + + var discoverer = new AssemblyTypeDiscoverer(); + var discoveryResult = discoverer.Discover(options.AssemblyPath!, configuration); + var transformer = new TypeTransformer(); + var generatedTypes = transformer.Transform(discoveryResult.Types, configuration); + var writer = new RoslynCodeWriter(); + var generationResult = writer.WriteFiles(generatedTypes, options.OutputDirectory!, configuration); + + Console.WriteLine($"Assembly: {Path.GetFullPath(options.AssemblyPath!)}"); + Console.WriteLine($"Output: {Path.GetFullPath(options.OutputDirectory!)}"); + Console.WriteLine($"Prefix: {configuration.ClassPrefix}"); + Console.WriteLine($"Discovered {discoveryResult.Types.Count} type(s) in {discoveryResult.AssemblyName}."); + Console.WriteLine($"Generated {generationResult.GeneratedFiles.Count} file(s)."); + return 0; + } + catch (Exception ex) + { + Console.Error.WriteLine(ex.Message); + return 1; + } + } + + private static string GetDefaultConfigurationOutputPath(string? configuredPath) + { + if (!string.IsNullOrWhiteSpace(configuredPath)) + { + return Path.GetFullPath(configuredPath); + } + + return Path.Combine(Environment.CurrentDirectory, "auth0-model-generator.json"); + } +} diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/README.md b/src/Alethic.Auth0.Operator.ModelGenerator/README.md new file mode 100644 index 0000000..b647b32 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/README.md @@ -0,0 +1,32 @@ +# Alethic.Auth0.Operator.ModelGenerator + +Refreshes copied Auth0 API model types by loading a source assembly, enumerating model classes, applying configurable transforms, and writing generated C# files. + +## Usage + +```powershell +dotnet run --project src/Alethic.Auth0.Operator.ModelGenerator -- \ + --assembly "C:\path\to\Auth0.ManagementApi.dll" \ + --output "D:\auth0-operator\artifacts\generated-models" \ + --config "src\Alethic.Auth0.Operator.ModelGenerator\connection-options-v2alpha1.json" +``` + +## Supported transforms + +- Prefix generated type names. +- Remap source namespaces to target namespaces. +- Restrict discovery by namespace and type-name prefixes. +- Remove selected source attributes. +- Ignore selected properties globally or by source type. +- Add standard type or property attributes. +- Append standard properties to every generated type. + +## Configuration workflow + +Start from an existing scenario-specific config such as `connection-options-v2alpha1.json` and adjust the transform rules as needed. + +You can also emit a fresh default file: + +```powershell +dotnet run --project src/Alethic.Auth0.Operator.ModelGenerator -- --write-default-config --config ".\connection-options-v2alpha1.json" +``` \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GeneratedAttribute.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GeneratedAttribute.cs new file mode 100644 index 0000000..53b6f2a --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GeneratedAttribute.cs @@ -0,0 +1,10 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Transformation; + +public sealed class GeneratedAttribute +{ + public required string TypeName { get; init; } + + public List ConstructorArguments { get; init; } = []; + + public Dictionary NamedArguments { get; init; } = new(StringComparer.Ordinal); +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GeneratedProperty.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GeneratedProperty.cs new file mode 100644 index 0000000..d28f21f --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GeneratedProperty.cs @@ -0,0 +1,18 @@ +using Alethic.Auth0.Operator.ModelGenerator.Discovery; + +namespace Alethic.Auth0.Operator.ModelGenerator.Transformation; + +public sealed class GeneratedProperty +{ + public required string Name { get; init; } + + public string? JsonPropertyName { get; init; } + + public string? Summary { get; init; } + + public required DiscoveredTypeReference Type { get; init; } + + public bool HasSetter { get; init; } = true; + + public List Attributes { get; init; } = []; +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GeneratedType.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GeneratedType.cs new file mode 100644 index 0000000..84be8b7 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GeneratedType.cs @@ -0,0 +1,18 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Transformation; + +public sealed class GeneratedType +{ + public required string Name { get; init; } + + public required string Namespace { get; init; } + + public bool IsEnumLike { get; init; } + + public List Attributes { get; init; } = []; + + public List Properties { get; init; } = []; + + public List<(string Name, string SerializedName)> EnumMembers { get; init; } = []; + + public List UsingDirectives { get; init; } = []; +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GenerationResult.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GenerationResult.cs new file mode 100644 index 0000000..23b5c25 --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/GenerationResult.cs @@ -0,0 +1,8 @@ +namespace Alethic.Auth0.Operator.ModelGenerator.Transformation; + +public sealed class GenerationResult +{ + public required string OutputDirectory { get; init; } + + public List GeneratedFiles { get; init; } = []; +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/TypeTransformer.cs b/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/TypeTransformer.cs new file mode 100644 index 0000000..f6e60da --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/Transformation/TypeTransformer.cs @@ -0,0 +1,572 @@ +using System.Text.RegularExpressions; + +using System.Text.Json.Serialization; + +using Alethic.Auth0.Operator.ModelGenerator.Configuration; +using Alethic.Auth0.Operator.ModelGenerator.Discovery; + +namespace Alethic.Auth0.Operator.ModelGenerator.Transformation; + +public sealed class TypeTransformer +{ + public IReadOnlyList Transform(IReadOnlyList discoveredTypes, GeneratorConfiguration configuration) + { + var filteredTypes = discoveredTypes + .Where(type => !IsConfiguredTypeReplacement(type, configuration)) + .ToList(); + + var generatedTypeMap = BuildGeneratedTypeMap(filteredTypes, configuration); + return filteredTypes.Select(type => TransformType(type, configuration, generatedTypeMap)).ToList(); + } + + private GeneratedType TransformType(DiscoveredType discoveredType, GeneratorConfiguration configuration, IReadOnlyDictionary generatedTypeMap) + { + var generatedTypeReference = generatedTypeMap[discoveredType.FullName]; + var generatedName = generatedTypeReference.Name; + var generatedNamespace = generatedTypeReference.Namespace; + + var properties = discoveredType.Properties + .Where(property => !ShouldIgnoreProperty(discoveredType, property, configuration)) + .Select(property => TransformProperty(property, configuration, generatedTypeMap)) + .Concat(configuration.StandardProperties.Select(TransformStandardProperty)) + .ToList(); + + var attributes = discoveredType.Attributes + .Where(attribute => !ShouldRemoveAttribute(attribute, configuration)) + .Select(MapAttribute) + .Concat(configuration.AddedTypeAttributes.Select(MapAttribute)) + .ToList(); + + var usingDirectives = CollectUsingDirectives(generatedNamespace, attributes, properties); + + return new GeneratedType + { + Name = generatedName, + Namespace = generatedNamespace, + IsEnumLike = discoveredType.IsEnumLike, + Attributes = attributes, + Properties = properties, + EnumMembers = [.. discoveredType.EnumMembers.Select(member => (member.Name, member.SerializedName))], + UsingDirectives = usingDirectives, + }; + } + + private GeneratedProperty TransformProperty(DiscoveredProperty property, GeneratorConfiguration configuration, IReadOnlyDictionary generatedTypeMap) + { + var transformedType = NormalizePropertyType(property.Type, generatedTypeMap, configuration, true); + var jsonPropertyName = GetJsonPropertyName(property); + var attributes = BuildPropertyAttributes(property, configuration, jsonPropertyName, transformedType); + + return new GeneratedProperty + { + Name = property.Name, + JsonPropertyName = jsonPropertyName, + Type = transformedType, + HasSetter = property.HasPublicSetter, + Attributes = attributes, + }; + } + + private GeneratedProperty TransformStandardProperty(GeneratedPropertyConfiguration property) + { + var attributes = property.Attributes.Select(MapAttribute).ToList(); + if (!string.IsNullOrWhiteSpace(property.JsonPropertyName) + && !attributes.Any(attribute => string.Equals(attribute.TypeName, typeof(JsonPropertyNameAttribute).FullName, StringComparison.Ordinal))) + { + attributes.Insert(0, new GeneratedAttribute + { + TypeName = nameof(JsonPropertyNameAttribute).Replace("Attribute", string.Empty), + ConstructorArguments = [$"\"{property.JsonPropertyName}\""], + }); + } + + return new GeneratedProperty + { + Name = property.Name, + JsonPropertyName = property.JsonPropertyName, + Summary = property.Summary, + Type = MakeTypeNullable(ParseConfiguredType(property.TypeName)), + HasSetter = true, + Attributes = attributes, + }; + } + + private static DiscoveredTypeReference ParseConfiguredType(string typeName) + { + var trimmed = typeName.Trim(); + var isNullable = trimmed.EndsWith("?", StringComparison.Ordinal); + if (isNullable) + { + trimmed = trimmed[..^1]; + } + + var arrayRank = 0; + while (trimmed.EndsWith("[]", StringComparison.Ordinal)) + { + arrayRank++; + trimmed = trimmed[..^2]; + } + + var aliasMap = new Dictionary(StringComparer.Ordinal) + { + ["bool"] = typeof(bool).FullName!, + ["byte"] = typeof(byte).FullName!, + ["char"] = typeof(char).FullName!, + ["decimal"] = typeof(decimal).FullName!, + ["double"] = typeof(double).FullName!, + ["float"] = typeof(float).FullName!, + ["int"] = typeof(int).FullName!, + ["long"] = typeof(long).FullName!, + ["object"] = typeof(object).FullName!, + ["sbyte"] = typeof(sbyte).FullName!, + ["short"] = typeof(short).FullName!, + ["string"] = typeof(string).FullName!, + ["uint"] = typeof(uint).FullName!, + ["ulong"] = typeof(ulong).FullName!, + ["ushort"] = typeof(ushort).FullName!, + }; + + if (arrayRank > 0) + { + var elementType = ParseConfiguredType(trimmed); + return new DiscoveredTypeReference + { + Name = elementType.Name, + Namespace = elementType.Namespace, + FullName = null, + Alias = null, + IsReferenceType = true, + IsNullableReferenceType = isNullable, + IsValueType = false, + IsNullableValueType = false, + IsOptionalWrapper = false, + IsArray = true, + ArrayRank = arrayRank, + ElementType = elementType, + GenericArguments = [], + }; + } + + aliasMap.TryGetValue(trimmed, out var fullName); + var namespaceSeparator = trimmed.LastIndexOf('.'); + + return new DiscoveredTypeReference + { + Name = namespaceSeparator >= 0 ? trimmed[(namespaceSeparator + 1)..] : trimmed, + Namespace = namespaceSeparator >= 0 ? trimmed[..namespaceSeparator] : string.Empty, + FullName = fullName ?? (namespaceSeparator >= 0 ? trimmed : null), + Alias = aliasMap.ContainsKey(trimmed) ? trimmed : null, + IsReferenceType = !aliasMap.ContainsKey(trimmed) || trimmed is "string" or "object", + IsNullableReferenceType = isNullable && (trimmed is "string" or "object" || namespaceSeparator >= 0), + IsValueType = trimmed is "bool" or "byte" or "char" or "decimal" or "double" or "float" or "int" or "long" or "sbyte" or "short" or "uint" or "ulong" or "ushort", + IsNullableValueType = isNullable && trimmed != "string" && !trimmed.EndsWith("]", StringComparison.Ordinal), + }; + } + + private static bool IsConfiguredTypeReplacement(DiscoveredType discoveredType, GeneratorConfiguration configuration) + { + return TryGetConfiguredTypeReplacement(discoveredType.FullName, discoveredType.Name, configuration, out _); + } + + private static Dictionary BuildGeneratedTypeMap(IReadOnlyList discoveredTypes, GeneratorConfiguration configuration) + { + var map = new Dictionary(StringComparer.Ordinal); + foreach (var discoveredType in discoveredTypes) + { + var rewrittenName = RewriteTypeName(StripSourcePrefixes(discoveredType.Name, configuration), configuration); + map[discoveredType.FullName] = new DiscoveredTypeReference + { + Name = configuration.ClassPrefix + rewrittenName, + Namespace = MapNamespace(discoveredType.Namespace, configuration), + FullName = discoveredType.FullName, + Alias = null, + IsReferenceType = true, + IsNullableReferenceType = false, + IsValueType = false, + IsNullableValueType = false, + IsOptionalWrapper = false, + IsArray = false, + ArrayRank = 0, + }; + } + + return map; + } + + private static List BuildPropertyAttributes(DiscoveredProperty property, GeneratorConfiguration configuration, string? jsonPropertyName, DiscoveredTypeReference transformedType) + { + var attributes = property.Attributes + .Where(attribute => !ShouldRemoveAttribute(attribute, configuration)) + .Select(MapAttribute) + .Concat(configuration.AddedPropertyAttributes.Select(MapAttribute)) + .ToList(); + + if (!string.IsNullOrWhiteSpace(jsonPropertyName) + && !attributes.Any(attribute => string.Equals(attribute.TypeName, nameof(JsonPropertyNameAttribute).Replace("Attribute", string.Empty), StringComparison.Ordinal) + || string.Equals(attribute.TypeName, typeof(JsonPropertyNameAttribute).FullName, StringComparison.Ordinal))) + { + attributes.Insert(0, new GeneratedAttribute + { + TypeName = nameof(JsonPropertyNameAttribute).Replace("Attribute", string.Empty), + ConstructorArguments = [$"\"{jsonPropertyName}\""], + }); + } + + if (ShouldAddNullWhenWritingNull(property, transformedType) + && !attributes.Any(IsWhenWritingNullJsonIgnoreAttribute)) + { + attributes.Add(new GeneratedAttribute + { + TypeName = nameof(JsonIgnoreAttribute).Replace("Attribute", string.Empty), + NamedArguments = new Dictionary(StringComparer.Ordinal) + { + ["Condition"] = "JsonIgnoreCondition.WhenWritingNull", + }, + }); + } + + return attributes; + } + + private static GeneratedAttribute MapAttribute(DiscoveredAttribute attribute) + { + return new GeneratedAttribute + { + TypeName = attribute.ShortTypeName, + ConstructorArguments = [.. attribute.ConstructorArguments], + NamedArguments = new Dictionary(attribute.NamedArguments, StringComparer.Ordinal), + }; + } + + private static GeneratedAttribute MapAttribute(AttributeConfiguration attribute) + { + return new GeneratedAttribute + { + TypeName = attribute.TypeName, + ConstructorArguments = [.. attribute.ConstructorArguments], + NamedArguments = new Dictionary(attribute.NamedArguments, StringComparer.Ordinal), + }; + } + + private static bool ShouldIgnoreProperty(DiscoveredType discoveredType, DiscoveredProperty property, GeneratorConfiguration configuration) + { + if (string.Equals(property.Name, "AdditionalProperties", StringComparison.Ordinal) + || property.Attributes.Any(attribute => + string.Equals(attribute.TypeName, typeof(JsonExtensionDataAttribute).FullName, StringComparison.Ordinal) + || string.Equals(attribute.ShortTypeName, nameof(JsonExtensionDataAttribute).Replace("Attribute", string.Empty), StringComparison.Ordinal))) + { + return true; + } + + if (configuration.IgnoredPropertyNames.Contains(property.Name, StringComparer.Ordinal)) + { + return true; + } + + return configuration.IgnoredPropertiesByType.TryGetValue(discoveredType.Name, out var ignoredProperties) + && ignoredProperties.Contains(property.Name, StringComparer.Ordinal); + } + + private static bool ShouldRemoveAttribute(DiscoveredAttribute attribute, GeneratorConfiguration configuration) + { + var candidates = new[] + { + attribute.TypeName, + attribute.ShortTypeName, + attribute.ShortTypeName + "Attribute", + }; + + return candidates.Any(candidate => configuration.RemovedAttributeTypeNames.Contains(candidate, StringComparer.Ordinal)); + } + + private static string? GetJsonPropertyName(DiscoveredProperty property) + { + var attribute = property.Attributes.FirstOrDefault(attribute => + string.Equals(attribute.TypeName, typeof(JsonPropertyNameAttribute).FullName, StringComparison.Ordinal) + || string.Equals(attribute.ShortTypeName, nameof(JsonPropertyNameAttribute).Replace("Attribute", string.Empty), StringComparison.Ordinal)); + + return attribute?.ConstructorArguments.FirstOrDefault()?.Trim('"'); + } + + private static bool ShouldAddNullWhenWritingNull(DiscoveredProperty property, DiscoveredTypeReference transformedType) + { + return transformedType.IsOptionalWrapper + || transformedType.IsNullableValueType + || transformedType.IsNullableReferenceType + || property.Attributes.Any(attribute => + string.Equals(attribute.TypeName, "System.Runtime.CompilerServices.NullableAttribute", StringComparison.Ordinal) + || string.Equals(attribute.ShortTypeName, "Nullable", StringComparison.Ordinal) + || string.Equals(attribute.TypeName, "Auth0.ManagementApi.Core.OptionalAttribute", StringComparison.Ordinal) + || string.Equals(attribute.ShortTypeName, "Optional", StringComparison.Ordinal)); + } + + private static bool IsWhenWritingNullJsonIgnoreAttribute(GeneratedAttribute attribute) + { + return (string.Equals(attribute.TypeName, nameof(JsonIgnoreAttribute).Replace("Attribute", string.Empty), StringComparison.Ordinal) + || string.Equals(attribute.TypeName, typeof(JsonIgnoreAttribute).FullName, StringComparison.Ordinal)) + && attribute.NamedArguments.TryGetValue("Condition", out var condition) + && string.Equals(condition, "JsonIgnoreCondition.WhenWritingNull", StringComparison.Ordinal); + } + + private static bool IsNullableValueTypeReference(DiscoveredTypeReference type) + { + return string.Equals(type.FullName, "System.Nullable`1", StringComparison.Ordinal) + || string.Equals(type.Name, "Nullable", StringComparison.Ordinal); + } + + private static bool IsEnumerableTypeReference(DiscoveredTypeReference type) + { + return string.Equals(type.FullName, "System.Collections.Generic.IEnumerable`1", StringComparison.Ordinal) + || string.Equals(type.Namespace, "System.Collections.Generic", StringComparison.Ordinal) + && string.Equals(type.Name, "IEnumerable", StringComparison.Ordinal); + } + + private static DiscoveredTypeReference NormalizePropertyType(DiscoveredTypeReference type, IReadOnlyDictionary generatedTypeMap, GeneratorConfiguration configuration, bool makeNullable) + { + if (IsNullableValueTypeReference(type) && type.GenericArguments.Count == 1) + { + var underlyingType = NormalizePropertyType(type.GenericArguments[0], generatedTypeMap, configuration, false); + return new DiscoveredTypeReference + { + Name = underlyingType.Name, + Namespace = underlyingType.Namespace, + FullName = underlyingType.FullName, + Alias = underlyingType.Alias, + IsReferenceType = underlyingType.IsReferenceType, + IsNullableReferenceType = underlyingType.IsNullableReferenceType, + IsValueType = underlyingType.IsValueType, + IsNullableValueType = true, + IsOptionalWrapper = type.IsOptionalWrapper || underlyingType.IsOptionalWrapper, + IsArray = underlyingType.IsArray, + ArrayRank = underlyingType.ArrayRank, + ElementType = underlyingType.ElementType, + GenericArguments = [.. underlyingType.GenericArguments], + }; + } + + if (IsEnumerableTypeReference(type) && type.GenericArguments.Count == 1) + { + var elementType = NormalizePropertyType(type.GenericArguments[0], generatedTypeMap, configuration, false); + return new DiscoveredTypeReference + { + Name = elementType.Name, + Namespace = elementType.Namespace, + FullName = elementType.FullName, + Alias = null, + IsReferenceType = true, + IsNullableReferenceType = makeNullable, + IsValueType = false, + IsNullableValueType = false, + IsOptionalWrapper = type.IsOptionalWrapper || elementType.IsOptionalWrapper, + IsArray = true, + ArrayRank = 1, + ElementType = elementType, + GenericArguments = [], + }; + } + + if (type.IsArray && type.ElementType is not null) + { + return new DiscoveredTypeReference + { + Name = type.Name, + Namespace = type.Namespace, + FullName = type.FullName, + Alias = type.Alias, + IsReferenceType = true, + IsNullableReferenceType = makeNullable, + IsValueType = false, + IsNullableValueType = false, + IsOptionalWrapper = type.IsOptionalWrapper, + IsArray = true, + ArrayRank = type.ArrayRank, + ElementType = NormalizePropertyType(type.ElementType, generatedTypeMap, configuration, false), + GenericArguments = [.. type.GenericArguments.Select(argument => NormalizePropertyType(argument, generatedTypeMap, configuration, false))], + }; + } + + if (TryGetConfiguredTypeReplacement(type.FullName, type.Name, configuration, out var replacementTypeName)) + { + var replacementType = ParseConfiguredType(replacementTypeName!); + return makeNullable + ? MakeTypeNullable(replacementType) + : replacementType; + } + + if (!string.IsNullOrWhiteSpace(type.FullName) && generatedTypeMap.TryGetValue(type.FullName, out var generatedType)) + { + return new DiscoveredTypeReference + { + Name = generatedType.Name, + Namespace = generatedType.Namespace, + FullName = generatedType.FullName, + Alias = null, + IsReferenceType = true, + IsNullableReferenceType = makeNullable || type.IsOptionalWrapper, + IsValueType = false, + IsNullableValueType = false, + IsOptionalWrapper = type.IsOptionalWrapper, + IsArray = false, + ArrayRank = 0, + GenericArguments = [.. type.GenericArguments.Select(argument => NormalizePropertyType(argument, generatedTypeMap, configuration, false))], + }; + } + + return new DiscoveredTypeReference + { + Name = type.Name, + Namespace = type.Namespace, + FullName = type.FullName, + Alias = type.Alias, + IsReferenceType = type.IsReferenceType, + IsNullableReferenceType = type.IsReferenceType && (makeNullable || type.IsNullableReferenceType || type.IsOptionalWrapper), + IsValueType = type.IsValueType, + IsNullableValueType = type.IsNullableValueType || (type.IsValueType && (makeNullable || type.IsOptionalWrapper)), + IsOptionalWrapper = type.IsOptionalWrapper, + IsArray = type.IsArray, + ArrayRank = type.ArrayRank, + ElementType = type.ElementType is null ? null : NormalizePropertyType(type.ElementType, generatedTypeMap, configuration, false), + GenericArguments = [.. type.GenericArguments.Select(argument => NormalizePropertyType(argument, generatedTypeMap, configuration, false))], + }; + } + + private static bool TryGetConfiguredTypeReplacement(string? fullName, string name, GeneratorConfiguration configuration, out string? replacementTypeName) + { + replacementTypeName = null; + + if (configuration.TypeReplacements.Count == 0) + { + return false; + } + + if (!string.IsNullOrWhiteSpace(fullName) && configuration.TypeReplacements.TryGetValue(fullName, out replacementTypeName)) + { + return true; + } + + return configuration.TypeReplacements.TryGetValue(name, out replacementTypeName); + } + + private static DiscoveredTypeReference MakeTypeNullable(DiscoveredTypeReference type) + { + return new DiscoveredTypeReference + { + Name = type.Name, + Namespace = type.Namespace, + FullName = type.FullName, + Alias = type.Alias, + IsReferenceType = type.IsReferenceType, + IsNullableReferenceType = type.IsReferenceType || type.IsArray || type.IsNullableReferenceType, + IsValueType = type.IsValueType, + IsNullableValueType = type.IsNullableValueType || type.IsValueType, + IsOptionalWrapper = type.IsOptionalWrapper, + IsArray = type.IsArray, + ArrayRank = type.ArrayRank, + ElementType = type.ElementType, + GenericArguments = [.. type.GenericArguments], + }; + } + + private static string StripSourcePrefixes(string name, GeneratorConfiguration configuration) + { + foreach (var prefix in configuration.SourceTypeNamePrefixes.OrderByDescending(prefix => prefix.Length)) + { + if (name.StartsWith(prefix, StringComparison.Ordinal)) + { + return name[prefix.Length..]; + } + } + + return name; + } + + private static string RewriteTypeName(string name, GeneratorConfiguration configuration) + { + var rewrittenName = name; + foreach (var rule in configuration.TypeNameRewriteRules) + { + rewrittenName = Regex.Replace(rewrittenName, rule.Pattern, rule.Replacement, RegexOptions.CultureInvariant); + } + + return rewrittenName; + } + + private static string MapNamespace(string sourceNamespace, GeneratorConfiguration configuration) + { + if (configuration.NamespaceMappings.TryGetValue(sourceNamespace, out var mappedNamespace)) + { + return mappedNamespace; + } + + if (!string.IsNullOrWhiteSpace(configuration.SourceNamespacePrefix) + && !string.IsNullOrWhiteSpace(configuration.TargetNamespacePrefix) + && sourceNamespace.StartsWith(configuration.SourceNamespacePrefix, StringComparison.Ordinal)) + { + return configuration.TargetNamespacePrefix + sourceNamespace[configuration.SourceNamespacePrefix.Length..]; + } + + return string.IsNullOrWhiteSpace(configuration.TargetNamespacePrefix) + ? sourceNamespace + : configuration.TargetNamespacePrefix; + } + + private static List CollectUsingDirectives(string generatedNamespace, List attributes, List properties) + { + var namespaces = new HashSet(StringComparer.Ordinal) + { + "System.Text.Json.Serialization", + }; + + foreach (var attribute in attributes) + { + TryAddAttributeNamespace(attribute, namespaces); + } + + foreach (var property in properties) + { + AddTypeNamespaces(property.Type, namespaces, generatedNamespace); + foreach (var attribute in property.Attributes) + { + TryAddAttributeNamespace(attribute, namespaces); + } + } + + return namespaces.OrderBy(name => name, StringComparer.Ordinal).ToList(); + } + + private static void TryAddAttributeNamespace(GeneratedAttribute attribute, HashSet namespaces) + { + if (attribute.TypeName.Contains('.', StringComparison.Ordinal)) + { + var separator = attribute.TypeName.LastIndexOf('.'); + if (separator > 0) + { + namespaces.Add(attribute.TypeName[..separator]); + } + } + else if (attribute.TypeName is "JsonPropertyName" or "JsonIgnore") + { + namespaces.Add("System.Text.Json.Serialization"); + } + } + + private static void AddTypeNamespaces(DiscoveredTypeReference type, HashSet namespaces, string generatedNamespace) + { + if (!string.IsNullOrWhiteSpace(type.Namespace) + && !string.Equals(type.Namespace, generatedNamespace, StringComparison.Ordinal) + && string.IsNullOrWhiteSpace(type.Alias)) + { + namespaces.Add(type.Namespace); + } + + if (type.IsArray && type.ElementType is not null) + { + AddTypeNamespaces(type.ElementType, namespaces, generatedNamespace); + } + + foreach (var argument in type.GenericArguments) + { + AddTypeNamespaces(argument, namespaces, generatedNamespace); + } + } +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/client-v2alpha1.json b/src/Alethic.Auth0.Operator.ModelGenerator/client-v2alpha1.json new file mode 100644 index 0000000..dc2f7ca --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/client-v2alpha1.json @@ -0,0 +1,86 @@ +{ + "classPrefix": "V2alpha1", + "sourceNamespacePrefix": "Auth0.ManagementApi", + "targetNamespacePrefix": "Alethic.Auth0.Operator.Core.Models.Client.V2alpha1", + "rootTypeNames": [ + "ClientAddons", + "ClientAppTypeEnum", + "ClientComplianceLevelEnum", + "ClientDefaultOrganization", + "ClientEncryptionKey", + "ClientJwtConfiguration", + "ClientMobile", + "ClientOidcBackchannelLogoutSettings", + "ClientOrganizationRequireBehaviorEnum", + "ClientOrganizationUsageEnum", + "ClientRefreshTokenConfiguration", + "ClientSigningKey", + "ClientTokenEndpointAuthMethodEnum" + ], + "followReferencedTypes": true, + "resolverAssemblyPaths": [ + "D:\\packages\\NuGet\\cache\\auth0.core\\7.46.0\\lib\\netstandard2.0\\Auth0.Core.dll", + "D:\\packages\\NuGet\\cache\\auth0.authenticationapi\\7.46.0\\lib\\netstandard2.0\\Auth0.AuthenticationApi.dll", + "D:\\packages\\NuGet\\cache\\portable.system.datetimeonly\\9.0.1\\lib\\netstandard2.0\\Portable.System.DateTimeOnly.dll" + ], + "sourceTypeNamePrefixes": [], + "includeNamespaces": [ + "Auth0.ManagementApi" + ], + "excludeTypeNames": [ + "AdditionalProperties", + "CreateClientRequestContent", + "GetClientRequestParameters", + "GetClientResponseContent", + "ReadOnlyAdditionalProperties", + "UpdateClientRequestContent" + ], + "ignoredPropertyNames": [ + "AdditionalProperties" + ], + "ignoredPropertiesByType": {}, + "removedAttributeTypeNames": [ + "JsonConverterAttribute", + "System.Text.Json.Serialization.JsonConverterAttribute", + "OptionalAttribute", + "Auth0.ManagementApi.Core.OptionalAttribute", + "JsonIgnoreAttribute", + "System.Text.Json.Serialization.JsonIgnoreAttribute", + "NullableAttribute", + "System.Runtime.CompilerServices.NullableAttribute", + "NullableContext", + "NullableContextAttribute", + "System.Runtime.CompilerServices.NullableContextAttribute", + "IsReadOnly", + "IsReadOnlyAttribute", + "System.Runtime.CompilerServices.IsReadOnlyAttribute", + "RequiredMember", + "RequiredMemberAttribute", + "System.Runtime.CompilerServices.RequiredMemberAttribute", + "CompilerFeatureRequired", + "CompilerFeatureRequiredAttribute", + "System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute", + "JsonAccess", + "JsonAccessAttribute", + "Auth0.ManagementApi.Core.JsonAccessAttribute", + "RequiredAttribute", + "System.ComponentModel.DataAnnotations.RequiredAttribute" + ], + "addedTypeAttributes": [], + "addedPropertyAttributes": [], + "standardProperties": [], + "namespaceMappings": {}, + "typeNameRewriteRules": [ + { + "pattern": "^(?!Client)(.+)$", + "replacement": "Client$1" + } + ], + "typeReplacements": { + "Auth0.ManagementApi.ClientAddonSharePointExternalUrl": "string[]?", + "ClientAddonSharePointExternalUrl": "string[]?" + }, + "emitRecords": true, + "useNamespaceSubdirectories": false, + "overwriteExistingFiles": true +} diff --git a/src/Alethic.Auth0.Operator.ModelGenerator/connection-options-v2alpha1.json b/src/Alethic.Auth0.Operator.ModelGenerator/connection-options-v2alpha1.json new file mode 100644 index 0000000..68b50cd --- /dev/null +++ b/src/Alethic.Auth0.Operator.ModelGenerator/connection-options-v2alpha1.json @@ -0,0 +1,85 @@ +{ + "classPrefix": "V2alpha1", + "sourceNamespacePrefix": "Auth0.ManagementApi", + "targetNamespacePrefix": "Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1", + "rootTypeNames": [ + "ConnectionOptions*", + "ConnectionUpstreamAliasEnum" + ], + "followReferencedTypes": true, + "resolverAssemblyPaths": [ + "D:\\packages\\NuGet\\cache\\auth0.core\\7.45.1\\lib\\netstandard2.0\\Auth0.Core.dll", + "D:\\packages\\NuGet\\cache\\auth0.authenticationapi\\7.45.1\\lib\\netstandard2.0\\Auth0.AuthenticationApi.dll", + "D:\\packages\\NuGet\\cache\\portable.system.datetimeonly\\9.0.1\\lib\\netstandard2.0\\Portable.System.DateTimeOnly.dll" + ], + "sourceTypeNamePrefixes": [], + "includeNamespaces": [ + "Auth0.ManagementApi" + ], + "excludeTypeNames": [ + "AdditionalProperties", + "ConnectionDecryptionKeySaml", + "ConnectionFieldsMapSamlValue", + "ConnectionOptionsIdpInitiatedClientProtocolEnumSamlSerializer", + "ConnectionOptionsProtocolEnumTwitterSerializer", + "ReadOnlyAdditionalProperties", + "ConnectionReadOnlyAdditionalProperties", + "ConnectionUpstreamAdditionalProperties", + "SelfServiceProfileSsoTicketConnectionOptions", + "UpdateConnectionOptions" + ], + "ignoredPropertyNames": [ + "AdditionalProperties" + ], + "ignoredPropertiesByType": {}, + "removedAttributeTypeNames": [ + "JsonConverterAttribute", + "System.Text.Json.Serialization.JsonConverterAttribute", + "OptionalAttribute", + "Auth0.ManagementApi.Core.OptionalAttribute", + "JsonIgnoreAttribute", + "System.Text.Json.Serialization.JsonIgnoreAttribute", + "NullableAttribute", + "System.Runtime.CompilerServices.NullableAttribute", + "NullableContext", + "NullableContextAttribute", + "System.Runtime.CompilerServices.NullableContextAttribute", + "IsReadOnly", + "IsReadOnlyAttribute", + "System.Runtime.CompilerServices.IsReadOnlyAttribute", + "RequiredMember", + "RequiredMemberAttribute", + "System.Runtime.CompilerServices.RequiredMemberAttribute", + "CompilerFeatureRequired", + "CompilerFeatureRequiredAttribute", + "System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute", + "JsonAccess", + "JsonAccessAttribute", + "Auth0.ManagementApi.Core.JsonAccessAttribute", + "RequiredAttribute", + "System.ComponentModel.DataAnnotations.RequiredAttribute" + ], + "addedTypeAttributes": [], + "addedPropertyAttributes": [], + "standardProperties": [], + "namespaceMappings": {}, + "typeNameRewriteRules": [ + { + "pattern": "^(?!Connection)(.+)$", + "replacement": "Connection$1" + } + ], + "typeReplacements": { + "Auth0.ManagementApi.ConnectionDecryptionKeySaml": "Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1.V2alpha1ConnectionDecryptionKeySaml", + "ConnectionDecryptionKeySaml": "Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1.V2alpha1ConnectionDecryptionKeySaml", + "Auth0.ManagementApi.ConnectionFieldsMapSamlValue": "string[]?", + "ConnectionFieldsMapSamlValue": "string[]?", + "Auth0.ManagementApi.ConnectionUpstreamAdditionalProperties": "Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1.V2alpha1ConnectionUpstreamAdditionalProperties", + "ConnectionUpstreamAdditionalProperties": "Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1.V2alpha1ConnectionUpstreamAdditionalProperties", + "Auth0.ManagementApi.Types.ConnectionScopeOAuth2": "string[]?", + "ConnectionScopeOAuth2": "string[]?" + }, + "emitRecords": true, + "useNamespaceSubdirectories": false, + "overwriteExistingFiles": true +} \ No newline at end of file diff --git a/src/Alethic.Auth0.Operator.Tests/Alethic.Auth0.Operator.Tests.csproj b/src/Alethic.Auth0.Operator.Tests/Alethic.Auth0.Operator.Tests.csproj index bdbdc56..446bff5 100644 --- a/src/Alethic.Auth0.Operator.Tests/Alethic.Auth0.Operator.Tests.csproj +++ b/src/Alethic.Auth0.Operator.Tests/Alethic.Auth0.Operator.Tests.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/src/Alethic.Auth0.Operator.Tests/ConnectionTests.cs b/src/Alethic.Auth0.Operator.Tests/ConnectionTests.cs deleted file mode 100644 index 2ba3972..0000000 --- a/src/Alethic.Auth0.Operator.Tests/ConnectionTests.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Threading.Tasks; - -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Alethic.Auth0.Operator.Tests -{ - - [TestClass] - public sealed class ConnectionTests - { - - static readonly Newtonsoft.Json.JsonSerializer _newtonsoftJsonSerializer = Newtonsoft.Json.JsonSerializer.CreateDefault(); - - [TestMethod] - public async Task TestMethod1() - { - //var api = new ManagementApiClient(@"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ilo5SlNydE8tYV9iT1J5c3RIaGZ3cSJ9.eyJpc3MiOiJodHRwczovL3RyYWlsbWF0ZXMtZGV2MS51cy5hdXRoMC5jb20vIiwic3ViIjoiWFFBMEcxVGtjUkhQTUEzY0xSSTFHRVBZcWhwbDFVcG1AY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vdHJhaWxtYXRlcy1kZXYxLnVzLmF1dGgwLmNvbS9hcGkvdjIvIiwiaWF0IjoxNzM2MTc1OTI3LCJleHAiOjE3MzYyNjIzMjcsInNjb3BlIjoicmVhZDpjbGllbnRfZ3JhbnRzIGNyZWF0ZTpjbGllbnRfZ3JhbnRzIGRlbGV0ZTpjbGllbnRfZ3JhbnRzIHVwZGF0ZTpjbGllbnRfZ3JhbnRzIHJlYWQ6dXNlcnMgdXBkYXRlOnVzZXJzIGRlbGV0ZTp1c2VycyBjcmVhdGU6dXNlcnMgcmVhZDp1c2Vyc19hcHBfbWV0YWRhdGEgdXBkYXRlOnVzZXJzX2FwcF9tZXRhZGF0YSBkZWxldGU6dXNlcnNfYXBwX21ldGFkYXRhIGNyZWF0ZTp1c2Vyc19hcHBfbWV0YWRhdGEgcmVhZDp1c2VyX2N1c3RvbV9ibG9ja3MgY3JlYXRlOnVzZXJfY3VzdG9tX2Jsb2NrcyBkZWxldGU6dXNlcl9jdXN0b21fYmxvY2tzIGNyZWF0ZTp1c2VyX3RpY2tldHMgcmVhZDpjbGllbnRzIHVwZGF0ZTpjbGllbnRzIGRlbGV0ZTpjbGllbnRzIGNyZWF0ZTpjbGllbnRzIHJlYWQ6Y2xpZW50X2tleXMgdXBkYXRlOmNsaWVudF9rZXlzIGRlbGV0ZTpjbGllbnRfa2V5cyBjcmVhdGU6Y2xpZW50X2tleXMgcmVhZDpjb25uZWN0aW9ucyB1cGRhdGU6Y29ubmVjdGlvbnMgZGVsZXRlOmNvbm5lY3Rpb25zIGNyZWF0ZTpjb25uZWN0aW9ucyByZWFkOnJlc291cmNlX3NlcnZlcnMgdXBkYXRlOnJlc291cmNlX3NlcnZlcnMgZGVsZXRlOnJlc291cmNlX3NlcnZlcnMgY3JlYXRlOnJlc291cmNlX3NlcnZlcnMgcmVhZDpkZXZpY2VfY3JlZGVudGlhbHMgdXBkYXRlOmRldmljZV9jcmVkZW50aWFscyBkZWxldGU6ZGV2aWNlX2NyZWRlbnRpYWxzIGNyZWF0ZTpkZXZpY2VfY3JlZGVudGlhbHMgcmVhZDpydWxlcyB1cGRhdGU6cnVsZXMgZGVsZXRlOnJ1bGVzIGNyZWF0ZTpydWxlcyByZWFkOnJ1bGVzX2NvbmZpZ3MgdXBkYXRlOnJ1bGVzX2NvbmZpZ3MgZGVsZXRlOnJ1bGVzX2NvbmZpZ3MgcmVhZDpob29rcyB1cGRhdGU6aG9va3MgZGVsZXRlOmhvb2tzIGNyZWF0ZTpob29rcyByZWFkOmFjdGlvbnMgdXBkYXRlOmFjdGlvbnMgZGVsZXRlOmFjdGlvbnMgY3JlYXRlOmFjdGlvbnMgcmVhZDplbWFpbF9wcm92aWRlciB1cGRhdGU6ZW1haWxfcHJvdmlkZXIgZGVsZXRlOmVtYWlsX3Byb3ZpZGVyIGNyZWF0ZTplbWFpbF9wcm92aWRlciBibGFja2xpc3Q6dG9rZW5zIHJlYWQ6c3RhdHMgcmVhZDppbnNpZ2h0cyByZWFkOnRlbmFudF9zZXR0aW5ncyB1cGRhdGU6dGVuYW50X3NldHRpbmdzIHJlYWQ6bG9ncyByZWFkOmxvZ3NfdXNlcnMgcmVhZDpzaGllbGRzIGNyZWF0ZTpzaGllbGRzIHVwZGF0ZTpzaGllbGRzIGRlbGV0ZTpzaGllbGRzIHJlYWQ6YW5vbWFseV9ibG9ja3MgZGVsZXRlOmFub21hbHlfYmxvY2tzIHVwZGF0ZTp0cmlnZ2VycyByZWFkOnRyaWdnZXJzIHJlYWQ6Z3JhbnRzIGRlbGV0ZTpncmFudHMgcmVhZDpndWFyZGlhbl9mYWN0b3JzIHVwZGF0ZTpndWFyZGlhbl9mYWN0b3JzIHJlYWQ6Z3VhcmRpYW5fZW5yb2xsbWVudHMgZGVsZXRlOmd1YXJkaWFuX2Vucm9sbG1lbnRzIGNyZWF0ZTpndWFyZGlhbl9lbnJvbGxtZW50X3RpY2tldHMgcmVhZDp1c2VyX2lkcF90b2tlbnMgY3JlYXRlOnBhc3N3b3Jkc19jaGVja2luZ19qb2IgZGVsZXRlOnBhc3N3b3Jkc19jaGVja2luZ19qb2IgcmVhZDpjdXN0b21fZG9tYWlucyBkZWxldGU6Y3VzdG9tX2RvbWFpbnMgY3JlYXRlOmN1c3RvbV9kb21haW5zIHVwZGF0ZTpjdXN0b21fZG9tYWlucyByZWFkOmVtYWlsX3RlbXBsYXRlcyBjcmVhdGU6ZW1haWxfdGVtcGxhdGVzIHVwZGF0ZTplbWFpbF90ZW1wbGF0ZXMgcmVhZDptZmFfcG9saWNpZXMgdXBkYXRlOm1mYV9wb2xpY2llcyByZWFkOnJvbGVzIGNyZWF0ZTpyb2xlcyBkZWxldGU6cm9sZXMgdXBkYXRlOnJvbGVzIHJlYWQ6cHJvbXB0cyB1cGRhdGU6cHJvbXB0cyByZWFkOmJyYW5kaW5nIHVwZGF0ZTpicmFuZGluZyBkZWxldGU6YnJhbmRpbmcgcmVhZDpsb2dfc3RyZWFtcyBjcmVhdGU6bG9nX3N0cmVhbXMgZGVsZXRlOmxvZ19zdHJlYW1zIHVwZGF0ZTpsb2dfc3RyZWFtcyBjcmVhdGU6c2lnbmluZ19rZXlzIHJlYWQ6c2lnbmluZ19rZXlzIHVwZGF0ZTpzaWduaW5nX2tleXMgcmVhZDpsaW1pdHMgdXBkYXRlOmxpbWl0cyBjcmVhdGU6cm9sZV9tZW1iZXJzIHJlYWQ6cm9sZV9tZW1iZXJzIGRlbGV0ZTpyb2xlX21lbWJlcnMgcmVhZDplbnRpdGxlbWVudHMgcmVhZDphdHRhY2tfcHJvdGVjdGlvbiB1cGRhdGU6YXR0YWNrX3Byb3RlY3Rpb24gcmVhZDpvcmdhbml6YXRpb25zX3N1bW1hcnkgY3JlYXRlOmF1dGhlbnRpY2F0aW9uX21ldGhvZHMgcmVhZDphdXRoZW50aWNhdGlvbl9tZXRob2RzIHVwZGF0ZTphdXRoZW50aWNhdGlvbl9tZXRob2RzIGRlbGV0ZTphdXRoZW50aWNhdGlvbl9tZXRob2RzIHJlYWQ6b3JnYW5pemF0aW9ucyB1cGRhdGU6b3JnYW5pemF0aW9ucyBjcmVhdGU6b3JnYW5pemF0aW9ucyBkZWxldGU6b3JnYW5pemF0aW9ucyBjcmVhdGU6b3JnYW5pemF0aW9uX21lbWJlcnMgcmVhZDpvcmdhbml6YXRpb25fbWVtYmVycyBkZWxldGU6b3JnYW5pemF0aW9uX21lbWJlcnMgY3JlYXRlOm9yZ2FuaXphdGlvbl9jb25uZWN0aW9ucyByZWFkOm9yZ2FuaXphdGlvbl9jb25uZWN0aW9ucyB1cGRhdGU6b3JnYW5pemF0aW9uX2Nvbm5lY3Rpb25zIGRlbGV0ZTpvcmdhbml6YXRpb25fY29ubmVjdGlvbnMgY3JlYXRlOm9yZ2FuaXphdGlvbl9tZW1iZXJfcm9sZXMgcmVhZDpvcmdhbml6YXRpb25fbWVtYmVyX3JvbGVzIGRlbGV0ZTpvcmdhbml6YXRpb25fbWVtYmVyX3JvbGVzIGNyZWF0ZTpvcmdhbml6YXRpb25faW52aXRhdGlvbnMgcmVhZDpvcmdhbml6YXRpb25faW52aXRhdGlvbnMgZGVsZXRlOm9yZ2FuaXphdGlvbl9pbnZpdGF0aW9ucyByZWFkOnNjaW1fY29uZmlnIGNyZWF0ZTpzY2ltX2NvbmZpZyB1cGRhdGU6c2NpbV9jb25maWcgZGVsZXRlOnNjaW1fY29uZmlnIGNyZWF0ZTpzY2ltX3Rva2VuIHJlYWQ6c2NpbV90b2tlbiBkZWxldGU6c2NpbV90b2tlbiBkZWxldGU6cGhvbmVfcHJvdmlkZXJzIGNyZWF0ZTpwaG9uZV9wcm92aWRlcnMgcmVhZDpwaG9uZV9wcm92aWRlcnMgdXBkYXRlOnBob25lX3Byb3ZpZGVycyBkZWxldGU6cGhvbmVfdGVtcGxhdGVzIGNyZWF0ZTpwaG9uZV90ZW1wbGF0ZXMgcmVhZDpwaG9uZV90ZW1wbGF0ZXMgdXBkYXRlOnBob25lX3RlbXBsYXRlcyBjcmVhdGU6ZW5jcnlwdGlvbl9rZXlzIHJlYWQ6ZW5jcnlwdGlvbl9rZXlzIHVwZGF0ZTplbmNyeXB0aW9uX2tleXMgZGVsZXRlOmVuY3J5cHRpb25fa2V5cyByZWFkOnNlc3Npb25zIGRlbGV0ZTpzZXNzaW9ucyByZWFkOnJlZnJlc2hfdG9rZW5zIGRlbGV0ZTpyZWZyZXNoX3Rva2VucyBjcmVhdGU6c2VsZl9zZXJ2aWNlX3Byb2ZpbGVzIHJlYWQ6c2VsZl9zZXJ2aWNlX3Byb2ZpbGVzIHVwZGF0ZTpzZWxmX3NlcnZpY2VfcHJvZmlsZXMgZGVsZXRlOnNlbGZfc2VydmljZV9wcm9maWxlcyBjcmVhdGU6c3NvX2FjY2Vzc190aWNrZXRzIGRlbGV0ZTpzc29fYWNjZXNzX3RpY2tldHMgcmVhZDpmb3JtcyB1cGRhdGU6Zm9ybXMgZGVsZXRlOmZvcm1zIGNyZWF0ZTpmb3JtcyByZWFkOmZsb3dzIHVwZGF0ZTpmbG93cyBkZWxldGU6Zmxvd3MgY3JlYXRlOmZsb3dzIHJlYWQ6Zmxvd3NfdmF1bHQgcmVhZDpmbG93c192YXVsdF9jb25uZWN0aW9ucyB1cGRhdGU6Zmxvd3NfdmF1bHRfY29ubmVjdGlvbnMgZGVsZXRlOmZsb3dzX3ZhdWx0X2Nvbm5lY3Rpb25zIGNyZWF0ZTpmbG93c192YXVsdF9jb25uZWN0aW9ucyByZWFkOmZsb3dzX2V4ZWN1dGlvbnMgZGVsZXRlOmZsb3dzX2V4ZWN1dGlvbnMgcmVhZDpjb25uZWN0aW9uc19vcHRpb25zIHVwZGF0ZTpjb25uZWN0aW9uc19vcHRpb25zIHJlYWQ6c2VsZl9zZXJ2aWNlX3Byb2ZpbGVfY3VzdG9tX3RleHRzIHVwZGF0ZTpzZWxmX3NlcnZpY2VfcHJvZmlsZV9jdXN0b21fdGV4dHMgcmVhZDpjbGllbnRfY3JlZGVudGlhbHMgY3JlYXRlOmNsaWVudF9jcmVkZW50aWFscyB1cGRhdGU6Y2xpZW50X2NyZWRlbnRpYWxzIGRlbGV0ZTpjbGllbnRfY3JlZGVudGlhbHMgcmVhZDpvcmdhbml6YXRpb25fY2xpZW50X2dyYW50cyBjcmVhdGU6b3JnYW5pemF0aW9uX2NsaWVudF9ncmFudHMgZGVsZXRlOm9yZ2FuaXphdGlvbl9jbGllbnRfZ3JhbnRzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIiwiYXpwIjoiWFFBMEcxVGtjUkhQTUEzY0xSSTFHRVBZcWhwbDFVcG0ifQ.iRwyhqziDxLKWJnBC6AudN-N8AMi5ngXKfd7zaHb6sJbFBk4XncM1IEIAPLMjrr8wTrR9HpxBiumC1pr53ybwsWIloP8cdgFAwFGxOWYPlASEHDupR4A52pNifLW2IDFoSwEMDhKl6jY7WYzkuBv6smX4Dwq-KT3GmxRD2VjBoIH2YWv_ueuenVwR2sR1hrYXarch8tWX2AEt1dGyPwjGKRBkDudta84X5YmmfyzEyic3af_mi07aYlnzxJcSeQRJBg6bAdx1uCKDZec3WbhlmZib7blFyQ3YjUBjAJsHGuG2BIXgMblpt7pvpHkkWt4YZl6yqYlGjSn5QnD7K_qKQ", new Uri($"https://trailmates-dev1.us.auth0.com/api/v2/")); - //var cnn = await api.Connections.GetAsync("con_KA3Z6UKXuE9j0zgR"); - - //using var w = new StringWriter(); - //_newtonsoftJsonSerializer.Serialize(w, cnn); - - //var opts = cnn.Options.ToObject(); - //var zsda = ((JObject)cnn.Options).ToDictionary(); - - //var to = System.Text.Json.JsonSerializer.Deserialize(w.ToString()); - //if (to is null) - // throw new InvalidOperationException(); - } - - } - -} diff --git a/src/Alethic.Auth0.Operator.Tests/V1ClientControllerMappingTests.cs b/src/Alethic.Auth0.Operator.Tests/V1ClientControllerMappingTests.cs deleted file mode 100644 index d3afaf9..0000000 --- a/src/Alethic.Auth0.Operator.Tests/V1ClientControllerMappingTests.cs +++ /dev/null @@ -1,656 +0,0 @@ -using System.Collections.Generic; - -using Alethic.Auth0.Operator.Controllers; -using Alethic.Auth0.Operator.Core.Models.Client.V1; - -using Auth0.ManagementApi.Models; - -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Alethic.Auth0.Operator.Tests -{ - - [TestClass] - public class V1ClientControllerMappingTests - { - - // ──────────────────────── FromApi null-guard tests ──────────────────────── - - [TestMethod] - public void FromApi_Client_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((Client?)null)); - } - - [TestMethod] - public void FromApi_SigningKey_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((SigningKey?)null)); - } - - [TestMethod] - public void FromApi_ClientResourceServerAssociation_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((ClientResourceServerAssociation?)null)); - } - - [TestMethod] - public void FromApi_RefreshToken_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((RefreshToken?)null)); - } - - [TestMethod] - public void FromApi_OidcLogoutConfig_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((OidcLogoutConfig?)null)); - } - - [TestMethod] - public void FromApi_BackchannelLogoutInitiators_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((BackchannelLogoutInitiators?)null)); - } - - [TestMethod] - public void FromApi_JwtConfiguration_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((JwtConfiguration?)null)); - } - - [TestMethod] - public void FromApi_Scopes_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((Scopes?)null)); - } - - [TestMethod] - public void FromApi_ScopeEntry_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((ScopeEntry?)null)); - } - - [TestMethod] - public void FromApi_EncryptionKey_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((EncryptionKey?)null)); - } - - [TestMethod] - public void FromApi_DefaultOrganization_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((DefaultOrganization?)null)); - } - - [TestMethod] - public void FromApi_Mobile_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((Mobile?)null)); - } - - [TestMethod] - public void FromApi_Addons_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((Addons?)null)); - } - - // ──────────────────────── FromApi TokenEndpointAuthMethod ───────────────── - - [TestMethod] - [DataRow(TokenEndpointAuthMethod.None, V1ClientTokenEndpointAuthMethod.None)] - [DataRow(TokenEndpointAuthMethod.ClientSecretPost, V1ClientTokenEndpointAuthMethod.ClientSecretPost)] - [DataRow(TokenEndpointAuthMethod.ClientSecretBasic, V1ClientTokenEndpointAuthMethod.ClientSecretBasic)] - public void FromApi_TokenEndpointAuthMethod_MapsCorrectly(TokenEndpointAuthMethod input, V1ClientTokenEndpointAuthMethod expected) - { - Assert.AreEqual(expected, V1ClientController.FromApi((TokenEndpointAuthMethod?)input)); - } - - [TestMethod] - public void FromApi_TokenEndpointAuthMethod_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((TokenEndpointAuthMethod?)null)); - } - - // ──────────────────────── FromApi RefreshTokenRotationType ──────────────── - - [TestMethod] - [DataRow(RefreshTokenRotationType.Rotating, V1ClientRefreshTokenRotationType.Rotating)] - [DataRow(RefreshTokenRotationType.NonRotating, V1ClientRefreshTokenRotationType.NonRotating)] - public void FromApi_RefreshTokenRotationType_MapsCorrectly(RefreshTokenRotationType input, V1ClientRefreshTokenRotationType expected) - { - Assert.AreEqual(expected, V1ClientController.FromApi((RefreshTokenRotationType?)input)); - } - - [TestMethod] - public void FromApi_RefreshTokenRotationType_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((RefreshTokenRotationType?)null)); - } - - // ──────────────────────── FromApi RefreshTokenExpirationType ────────────── - - [TestMethod] - [DataRow(RefreshTokenExpirationType.Expiring, V1ClientRefreshTokenExpirationType.Expiring)] - [DataRow(RefreshTokenExpirationType.NonExpiring, V1ClientRefreshTokenExpirationType.NonExpiring)] - public void FromApi_RefreshTokenExpirationType_MapsCorrectly(RefreshTokenExpirationType input, V1ClientRefreshTokenExpirationType expected) - { - Assert.AreEqual(expected, V1ClientController.FromApi((RefreshTokenExpirationType?)input)); - } - - [TestMethod] - public void FromApi_RefreshTokenExpirationType_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((RefreshTokenExpirationType?)null)); - } - - // ──────────────────────── FromApi OrganizationUsage ─────────────────────── - - [TestMethod] - [DataRow(OrganizationUsage.Deny, V1ClientOrganizationUsage.Deny)] - [DataRow(OrganizationUsage.Allow, V1ClientOrganizationUsage.Allow)] - [DataRow(OrganizationUsage.Require, V1ClientOrganizationUsage.Require)] - public void FromApi_OrganizationUsage_MapsCorrectly(OrganizationUsage input, V1ClientOrganizationUsage expected) - { - Assert.AreEqual(expected, V1ClientController.FromApi((OrganizationUsage?)input)); - } - - [TestMethod] - public void FromApi_OrganizationUsage_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((OrganizationUsage?)null)); - } - - // ──────────────────────── FromApi OrganizationRequireBehavior ───────────── - - [TestMethod] - [DataRow(OrganizationRequireBehavior.NoPrompt, V1ClientOrganizationRequireBehavior.NoPrompt)] - [DataRow(OrganizationRequireBehavior.PreLoginPrompt, V1ClientOrganizationRequireBehavior.PreLoginPrompt)] - [DataRow(OrganizationRequireBehavior.PostLoginPrompt, V1ClientOrganizationRequireBehavior.PostLoginPrompt)] - public void FromApi_OrganizationRequireBehavior_MapsCorrectly(OrganizationRequireBehavior input, V1ClientOrganizationRequireBehavior expected) - { - Assert.AreEqual(expected, V1ClientController.FromApi((OrganizationRequireBehavior?)input)); - } - - [TestMethod] - public void FromApi_OrganizationRequireBehavior_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((OrganizationRequireBehavior?)null)); - } - - // ──────────────────────── FromApi LogoutInitiators ──────────────────────── - - [TestMethod] - [DataRow(LogoutInitiators.RpLogout, V1ClientLogoutInitiators.RpLogout)] - [DataRow(LogoutInitiators.IdpLogout, V1ClientLogoutInitiators.IdpLogout)] - [DataRow(LogoutInitiators.PasswordChanged, V1ClientLogoutInitiators.PasswordChanged)] - [DataRow(LogoutInitiators.SessionExpired, V1ClientLogoutInitiators.SessionExpired)] - public void FromApi_LogoutInitiators_MapsCorrectly(LogoutInitiators input, V1ClientLogoutInitiators expected) - { - Assert.AreEqual(expected, V1ClientController.FromApi(input)); - } - - // ──────────────────────── FromApi LogoutInitiatorModes ──────────────────── - - [TestMethod] - [DataRow(LogoutInitiatorModes.All, V1ClientLogoutInitiatorModes.All)] - [DataRow(LogoutInitiatorModes.Custom, V1ClientLogoutInitiatorModes.Custom)] - public void FromApi_LogoutInitiatorModes_MapsCorrectly(LogoutInitiatorModes input, V1ClientLogoutInitiatorModes expected) - { - Assert.AreEqual(expected, V1ClientController.FromApi((LogoutInitiatorModes?)input)); - } - - [TestMethod] - public void FromApi_LogoutInitiatorModes_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((LogoutInitiatorModes?)null)); - } - - // ──────────────────────── FromApi ComplianceLevel ──────────────────────── - - [TestMethod] - [DataRow(ComplianceLevel.NONE, V1ClientComplianceLevel.NONE)] - [DataRow(ComplianceLevel.FAPI1_ADV_PKJ_PAR, V1ClientComplianceLevel.FAPI1_ADV_PKJ_PAR)] - [DataRow(ComplianceLevel.FAPI1_ADV_MTLS_PAR, V1ClientComplianceLevel.FAPI1_ADV_MTLS_PAR)] - public void FromApi_ComplianceLevel_MapsCorrectly(ComplianceLevel input, V1ClientComplianceLevel expected) - { - Assert.AreEqual(expected, V1ClientController.FromApi((ComplianceLevel?)input)); - } - - [TestMethod] - public void FromApi_ComplianceLevel_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((ComplianceLevel?)null)); - } - - // ──────────────────────── FromApi Flows ─────────────────────────────────── - - [TestMethod] - public void FromApi_Flows_ClientCredentials_MapsCorrectly() - { - Assert.AreEqual(V1ClientFlows.ClientCredentials, V1ClientController.FromApi(Flows.ClientCredentials)); - } - - // ──────────────────────── FromApi ClientApplicationType ────────────────── - - [TestMethod] - [DataRow(ClientApplicationType.Native, V1ClientApplicationType.Native)] - [DataRow(ClientApplicationType.NonInteractive, V1ClientApplicationType.NonInteractive)] - [DataRow(ClientApplicationType.Spa, V1ClientApplicationType.Spa)] - [DataRow(ClientApplicationType.RegularWeb, V1ClientApplicationType.RegularWeb)] - [DataRow(ClientApplicationType.Box, V1ClientApplicationType.Box)] - [DataRow(ClientApplicationType.Cloudbees, V1ClientApplicationType.Cloudbees)] - [DataRow(ClientApplicationType.Concur, V1ClientApplicationType.Concur)] - [DataRow(ClientApplicationType.Dropbox, V1ClientApplicationType.Dropbox)] - [DataRow(ClientApplicationType.Echosign, V1ClientApplicationType.Echosign)] - [DataRow(ClientApplicationType.Egnyte, V1ClientApplicationType.Egnyte)] - [DataRow(ClientApplicationType.MsCrm, V1ClientApplicationType.MsCrm)] - [DataRow(ClientApplicationType.NewRelic, V1ClientApplicationType.NewRelic)] - [DataRow(ClientApplicationType.Office365, V1ClientApplicationType.Office365)] - [DataRow(ClientApplicationType.Rms, V1ClientApplicationType.Rms)] - [DataRow(ClientApplicationType.Salesforce, V1ClientApplicationType.Salesforce)] - [DataRow(ClientApplicationType.Sentry, V1ClientApplicationType.Sentry)] - [DataRow(ClientApplicationType.SharePoint, V1ClientApplicationType.SharePoint)] - [DataRow(ClientApplicationType.Slack, V1ClientApplicationType.Slack)] - [DataRow(ClientApplicationType.SpringCm, V1ClientApplicationType.SpringCm)] - [DataRow(ClientApplicationType.Zendesk, V1ClientApplicationType.Zendesk)] - [DataRow(ClientApplicationType.Zoom, V1ClientApplicationType.Zoom)] - [DataRow(ClientApplicationType.ResourceServer, V1ClientApplicationType.ResourceServer)] - [DataRow(ClientApplicationType.ExpressConfiguration, V1ClientApplicationType.ExpressConfiguration)] - [DataRow(ClientApplicationType.SsoIntegration, V1ClientApplicationType.SsoIntegration)] - [DataRow(ClientApplicationType.Oag, V1ClientApplicationType.Oag)] - public void FromApi_ClientApplicationType_MapsCorrectly(ClientApplicationType input, V1ClientApplicationType expected) - { - Assert.AreEqual(expected, V1ClientController.FromApi((ClientApplicationType?)input)); - } - - [TestMethod] - public void FromApi_ClientApplicationType_Null_Returns_Null() - { - Assert.IsNull(V1ClientController.FromApi((ClientApplicationType?)null)); - } - - // ──────────────────────── FromApi value objects ─────────────────────────── - - [TestMethod] - public void FromApi_SigningKey_MapsProperties() - { - var source = new SigningKey { Cert = "cert", Key = "key", Pkcs7 = "pkcs7" }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.AreEqual("cert", result.Cert); - Assert.AreEqual("key", result.Key); - Assert.AreEqual("pkcs7", result.Pkcs7); - } - - [TestMethod] - public void FromApi_ClientResourceServerAssociation_MapsProperties() - { - var source = new ClientResourceServerAssociation { Identifier = "https://api.example.com", Scopes = ["read:data"] }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.AreEqual("https://api.example.com", result.Identifier); - CollectionAssert.AreEqual(new[] { "read:data" }, result.Scopes); - } - - [TestMethod] - public void FromApi_EncryptionKey_MapsProperties() - { - var source = new EncryptionKey { Certificate = "cert", PublicKey = "pub", Subject = "sub" }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.AreEqual("cert", result.Certificate); - Assert.AreEqual("pub", result.PublicKey); - Assert.AreEqual("sub", result.Subject); - } - - [TestMethod] - public void FromApi_ScopeEntry_MapsActions() - { - var source = new ScopeEntry { Actions = ["read", "write"] }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - CollectionAssert.AreEqual(new[] { "read", "write" }, result.Actions); - } - - [TestMethod] - public void FromApi_JwtConfiguration_MapsProperties() - { - var source = new JwtConfiguration { IsSecretEncoded = true, LifetimeInSeconds = 3600, SigningAlgorithm = "RS256" }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.AreEqual(true, result.IsSecretEncoded); - Assert.AreEqual(3600, result.LifetimeInSeconds); - Assert.AreEqual("RS256", result.SigningAlgorithm); - } - - [TestMethod] - public void FromApi_RefreshToken_MapsProperties() - { - var source = new RefreshToken - { - RotationType = RefreshTokenRotationType.Rotating, - ExpirationType = RefreshTokenExpirationType.Expiring, - Leeway = 10, - TokenLifetime = 86400, - InfiniteTokenLifetime = false, - InfiniteIdleTokenLifetime = false, - }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.AreEqual(V1ClientRefreshTokenRotationType.Rotating, result.RotationType); - Assert.AreEqual(V1ClientRefreshTokenExpirationType.Expiring, result.ExpirationType); - Assert.AreEqual(10, result.Leeway); - Assert.AreEqual(86400, result.TokenLifetime); - Assert.AreEqual(false, result.InfiniteTokenLifetime); - Assert.AreEqual(false, result.InfiniteIdleTokenLifetime); - } - - [TestMethod] - public void FromApi_OidcLogoutConfig_MapsBackchannelLogoutUrls() - { - var source = new OidcLogoutConfig { BackchannelLogoutUrls = ["https://example.com/logout"] }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - CollectionAssert.AreEqual(new[] { "https://example.com/logout" }, result.BackchannelLogoutUrls); - } - - [TestMethod] - public void FromApi_BackchannelLogoutInitiators_MapsProperties() - { - var source = new BackchannelLogoutInitiators - { - Mode = LogoutInitiatorModes.Custom, - SelectedInitiators = [LogoutInitiators.RpLogout, LogoutInitiators.IdpLogout], - }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.AreEqual(V1ClientLogoutInitiatorModes.Custom, result.Mode); - Assert.IsNotNull(result.SelectedInitiators); - Assert.AreEqual(2, result.SelectedInitiators.Length); - Assert.AreEqual(V1ClientLogoutInitiators.RpLogout, result.SelectedInitiators[0]); - Assert.AreEqual(V1ClientLogoutInitiators.IdpLogout, result.SelectedInitiators[1]); - } - - [TestMethod] - public void FromApi_DefaultOrganization_MapsProperties() - { - var source = new DefaultOrganization { OrganizationId = "org_123", Flows = [Flows.ClientCredentials] }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.AreEqual("org_123", result.OrganizationId); - Assert.IsNotNull(result.Flows); - Assert.AreEqual(1, result.Flows.Length); - Assert.AreEqual(V1ClientFlows.ClientCredentials, result.Flows[0]); - } - - [TestMethod] - public void FromApi_Mobile_WithIosAndAndroid_MapsProperties() - { - var source = new Mobile - { - Ios = new Mobile.MobileIos { AppBundleIdentifier = "com.example.app", TeamId = "TEAM123" }, - Android = new Mobile.MobileAndroid { AppPackageName = "com.example.app", KeystoreHash = "hash" }, - }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.IsNotNull(result.Ios); - Assert.AreEqual("com.example.app", result.Ios.AppBundleIdentifier); - Assert.AreEqual("TEAM123", result.Ios.TeamId); - Assert.IsNotNull(result.Android); - Assert.AreEqual("com.example.app", result.Android.AppPackageName); - Assert.AreEqual("hash", result.Android.KeystoreHash); - } - - [TestMethod] - public void FromApi_Mobile_WithEmptyIos_Returns_NullIos() - { - var source = new Mobile { Ios = new Mobile.MobileIos { AppBundleIdentifier = null, TeamId = null } }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.IsNull(result.Ios); - } - - [TestMethod] - public void FromApi_Mobile_WithEmptyAndroid_Returns_NullAndroid() - { - var source = new Mobile { Android = new Mobile.MobileAndroid { AppPackageName = null, KeystoreHash = null } }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.IsNull(result.Android); - } - - [TestMethod] - public void FromApi_Client_MapsScalarProperties() - { - var source = new Client - { - Name = "My App", - Description = "Test app", - LogoUri = "https://example.com/logo.png", - OidcConformant = true, - Sso = false, - CrossOriginAuthentication = true, - IsFirstParty = true, - ApplicationType = ClientApplicationType.RegularWeb, - TokenEndpointAuthMethod = TokenEndpointAuthMethod.ClientSecretPost, - }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - Assert.AreEqual("My App", result.Name); - Assert.AreEqual("Test app", result.Description); - Assert.AreEqual("https://example.com/logo.png", result.LogoUri); - Assert.AreEqual(true, result.OidcConformant); - Assert.AreEqual(false, result.Sso); - Assert.AreEqual(true, result.CrossOriginAuthentication); - Assert.AreEqual(true, result.IsFirstParty); - Assert.AreEqual(V1ClientApplicationType.RegularWeb, result.ApplicationType); - Assert.AreEqual(V1ClientTokenEndpointAuthMethod.ClientSecretPost, result.TokenEndpointAuthMethod); - } - - [TestMethod] - public void FromApi_Client_MapsArrayProperties() - { - var source = new Client - { - Name = "My App", - AllowedClients = ["client1", "client2"], - AllowedLogoutUrls = ["https://example.com/logout"], - AllowedOrigins = ["https://example.com"], - WebOrigins = ["https://example.com"], - Callbacks = ["https://example.com/callback"], - ClientAliases = ["alias1"], - GrantTypes = ["authorization_code", "refresh_token"], - }; - var result = V1ClientController.FromApi(source); - Assert.IsNotNull(result); - CollectionAssert.AreEqual(new[] { "client1", "client2" }, result.AllowedClients); - CollectionAssert.AreEqual(new[] { "https://example.com/logout" }, result.AllowedLogoutUrls); - CollectionAssert.AreEqual(new[] { "https://example.com" }, result.AllowedOrigins); - CollectionAssert.AreEqual(new[] { "https://example.com" }, result.WebOrigins); - CollectionAssert.AreEqual(new[] { "https://example.com/callback" }, result.Callbacks); - CollectionAssert.AreEqual(new[] { "alias1" }, result.ClientAliases); - CollectionAssert.AreEqual(new[] { "authorization_code", "refresh_token" }, result.GrantTypes); - } - - // ──────────────────────── ToApi ─────────────────────────────────────────── - - [TestMethod] - [DataRow(V1ClientComplianceLevel.NONE, ComplianceLevel.NONE)] - [DataRow(V1ClientComplianceLevel.FAPI1_ADV_PKJ_PAR, ComplianceLevel.FAPI1_ADV_PKJ_PAR)] - [DataRow(V1ClientComplianceLevel.FAPI1_ADV_MTLS_PAR, ComplianceLevel.FAPI1_ADV_MTLS_PAR)] - public void ToApi_ComplianceLevel_MapsCorrectly(V1ClientComplianceLevel input, ComplianceLevel expected) - { - Assert.AreEqual(expected, V1ClientController.ToApi(input)); - } - - [TestMethod] - [DataRow(V1ClientOrganizationRequireBehavior.NoPrompt, OrganizationRequireBehavior.NoPrompt)] - [DataRow(V1ClientOrganizationRequireBehavior.PreLoginPrompt, OrganizationRequireBehavior.PreLoginPrompt)] - [DataRow(V1ClientOrganizationRequireBehavior.PostLoginPrompt, OrganizationRequireBehavior.PostLoginPrompt)] - public void ToApi_OrganizationRequireBehavior_MapsCorrectly(V1ClientOrganizationRequireBehavior input, OrganizationRequireBehavior expected) - { - Assert.AreEqual(expected, V1ClientController.ToApi(input)); - } - - [TestMethod] - [DataRow(V1ClientOrganizationUsage.Deny, OrganizationUsage.Deny)] - [DataRow(V1ClientOrganizationUsage.Allow, OrganizationUsage.Allow)] - [DataRow(V1ClientOrganizationUsage.Require, OrganizationUsage.Require)] - public void ToApi_OrganizationUsage_MapsCorrectly(V1ClientOrganizationUsage input, OrganizationUsage expected) - { - Assert.AreEqual(expected, V1ClientController.ToApi(input)); - } - - [TestMethod] - [DataRow(V1ClientRefreshTokenRotationType.Rotating, RefreshTokenRotationType.Rotating)] - [DataRow(V1ClientRefreshTokenRotationType.NonRotating, RefreshTokenRotationType.NonRotating)] - public void ToApi_RefreshTokenRotationType_MapsCorrectly(V1ClientRefreshTokenRotationType input, RefreshTokenRotationType expected) - { - Assert.AreEqual(expected, V1ClientController.ToApi(input)); - } - - [TestMethod] - [DataRow(V1ClientRefreshTokenExpirationType.Expiring, RefreshTokenExpirationType.Expiring)] - [DataRow(V1ClientRefreshTokenExpirationType.NonExpiring, RefreshTokenExpirationType.NonExpiring)] - public void ToApi_RefreshTokenExpirationType_MapsCorrectly(V1ClientRefreshTokenExpirationType input, RefreshTokenExpirationType expected) - { - Assert.AreEqual(expected, V1ClientController.ToApi(input)); - } - - [TestMethod] - [DataRow(V1ClientLogoutInitiatorModes.All, LogoutInitiatorModes.All)] - [DataRow(V1ClientLogoutInitiatorModes.Custom, LogoutInitiatorModes.Custom)] - public void ToApi_LogoutInitiatorModes_MapsCorrectly(V1ClientLogoutInitiatorModes input, LogoutInitiatorModes expected) - { - Assert.AreEqual(expected, V1ClientController.ToApi(input)); - } - - [TestMethod] - [DataRow(V1ClientLogoutInitiators.RpLogout, LogoutInitiators.RpLogout)] - [DataRow(V1ClientLogoutInitiators.IdpLogout, LogoutInitiators.IdpLogout)] - [DataRow(V1ClientLogoutInitiators.PasswordChanged, LogoutInitiators.PasswordChanged)] - [DataRow(V1ClientLogoutInitiators.SessionExpired, LogoutInitiators.SessionExpired)] - public void ToApi_LogoutInitiators_MapsCorrectly(V1ClientLogoutInitiators input, LogoutInitiators expected) - { - Assert.AreEqual(expected, V1ClientController.ToApi(input)); - } - - [TestMethod] - [DataRow(V1ClientApplicationType.Box, ClientApplicationType.Box)] - [DataRow(V1ClientApplicationType.Cloudbees, ClientApplicationType.Cloudbees)] - [DataRow(V1ClientApplicationType.Concur, ClientApplicationType.Concur)] - [DataRow(V1ClientApplicationType.Dropbox, ClientApplicationType.Dropbox)] - [DataRow(V1ClientApplicationType.Echosign, ClientApplicationType.Echosign)] - [DataRow(V1ClientApplicationType.Egnyte, ClientApplicationType.Egnyte)] - [DataRow(V1ClientApplicationType.MsCrm, ClientApplicationType.MsCrm)] - [DataRow(V1ClientApplicationType.Native, ClientApplicationType.Native)] - [DataRow(V1ClientApplicationType.NewRelic, ClientApplicationType.NewRelic)] - [DataRow(V1ClientApplicationType.NonInteractive, ClientApplicationType.NonInteractive)] - [DataRow(V1ClientApplicationType.Office365, ClientApplicationType.Office365)] - [DataRow(V1ClientApplicationType.RegularWeb, ClientApplicationType.RegularWeb)] - [DataRow(V1ClientApplicationType.Rms, ClientApplicationType.Rms)] - [DataRow(V1ClientApplicationType.Salesforce, ClientApplicationType.Salesforce)] - [DataRow(V1ClientApplicationType.Sentry, ClientApplicationType.Sentry)] - [DataRow(V1ClientApplicationType.SharePoint, ClientApplicationType.SharePoint)] - [DataRow(V1ClientApplicationType.Slack, ClientApplicationType.Slack)] - [DataRow(V1ClientApplicationType.SpringCm, ClientApplicationType.SpringCm)] - [DataRow(V1ClientApplicationType.Spa, ClientApplicationType.Spa)] - [DataRow(V1ClientApplicationType.Zendesk, ClientApplicationType.Zendesk)] - [DataRow(V1ClientApplicationType.Zoom, ClientApplicationType.Zoom)] - public void ToApi_ClientApplicationType_MapsCorrectly(V1ClientApplicationType input, ClientApplicationType expected) - { - Assert.AreEqual(expected, V1ClientController.ToApi(input)); - } - - [TestMethod] - [DataRow(V1ClientTokenEndpointAuthMethod.None, TokenEndpointAuthMethod.None)] - [DataRow(V1ClientTokenEndpointAuthMethod.ClientSecretPost, TokenEndpointAuthMethod.ClientSecretPost)] - [DataRow(V1ClientTokenEndpointAuthMethod.ClientSecretBasic, TokenEndpointAuthMethod.ClientSecretBasic)] - public void ToApi_TokenEndpointAuthMethod_MapsCorrectly(V1ClientTokenEndpointAuthMethod input, TokenEndpointAuthMethod expected) - { - Assert.AreEqual(expected, V1ClientController.ToApi(input)); - } - - // ──────────────────────── Roundtrip tests ───────────────────────────────── - - [TestMethod] - [DataRow(TokenEndpointAuthMethod.None)] - [DataRow(TokenEndpointAuthMethod.ClientSecretPost)] - [DataRow(TokenEndpointAuthMethod.ClientSecretBasic)] - public void TokenEndpointAuthMethod_Roundtrip(TokenEndpointAuthMethod input) - { - var op = V1ClientController.FromApi((TokenEndpointAuthMethod?)input)!.Value; - Assert.AreEqual(input, V1ClientController.ToApi(op)); - } - - [TestMethod] - [DataRow(RefreshTokenRotationType.Rotating)] - [DataRow(RefreshTokenRotationType.NonRotating)] - public void RefreshTokenRotationType_Roundtrip(RefreshTokenRotationType input) - { - var op = V1ClientController.FromApi((RefreshTokenRotationType?)input)!.Value; - Assert.AreEqual(input, V1ClientController.ToApi(op)); - } - - [TestMethod] - [DataRow(RefreshTokenExpirationType.Expiring)] - [DataRow(RefreshTokenExpirationType.NonExpiring)] - public void RefreshTokenExpirationType_Roundtrip(RefreshTokenExpirationType input) - { - var op = V1ClientController.FromApi((RefreshTokenExpirationType?)input)!.Value; - Assert.AreEqual(input, V1ClientController.ToApi(op)); - } - - [TestMethod] - [DataRow(OrganizationUsage.Deny)] - [DataRow(OrganizationUsage.Allow)] - [DataRow(OrganizationUsage.Require)] - public void OrganizationUsage_Roundtrip(OrganizationUsage input) - { - var op = V1ClientController.FromApi((OrganizationUsage?)input)!.Value; - Assert.AreEqual(input, V1ClientController.ToApi(op)); - } - - [TestMethod] - [DataRow(OrganizationRequireBehavior.NoPrompt)] - [DataRow(OrganizationRequireBehavior.PreLoginPrompt)] - [DataRow(OrganizationRequireBehavior.PostLoginPrompt)] - public void OrganizationRequireBehavior_Roundtrip(OrganizationRequireBehavior input) - { - var op = V1ClientController.FromApi((OrganizationRequireBehavior?)input)!.Value; - Assert.AreEqual(input, V1ClientController.ToApi(op)); - } - - [TestMethod] - [DataRow(ComplianceLevel.NONE)] - [DataRow(ComplianceLevel.FAPI1_ADV_PKJ_PAR)] - [DataRow(ComplianceLevel.FAPI1_ADV_MTLS_PAR)] - public void ComplianceLevel_Roundtrip(ComplianceLevel input) - { - var op = V1ClientController.FromApi((ComplianceLevel?)input)!.Value; - Assert.AreEqual(input, V1ClientController.ToApi(op)); - } - - [TestMethod] - [DataRow(LogoutInitiators.RpLogout)] - [DataRow(LogoutInitiators.IdpLogout)] - [DataRow(LogoutInitiators.PasswordChanged)] - [DataRow(LogoutInitiators.SessionExpired)] - public void LogoutInitiators_Roundtrip(LogoutInitiators input) - { - var op = V1ClientController.FromApi(input); - Assert.AreEqual(input, V1ClientController.ToApi(op)); - } - - [TestMethod] - [DataRow(LogoutInitiatorModes.All)] - [DataRow(LogoutInitiatorModes.Custom)] - public void LogoutInitiatorModes_Roundtrip(LogoutInitiatorModes input) - { - var op = V1ClientController.FromApi((LogoutInitiatorModes?)input)!.Value; - Assert.AreEqual(input, V1ClientController.ToApi(op)); - } - - } - -} diff --git a/src/Alethic.Auth0.Operator.Tests/V1ClientGrantControllerMappingTests.cs b/src/Alethic.Auth0.Operator.Tests/V1ClientGrantControllerMappingTests.cs index cc28850..48fb739 100644 --- a/src/Alethic.Auth0.Operator.Tests/V1ClientGrantControllerMappingTests.cs +++ b/src/Alethic.Auth0.Operator.Tests/V1ClientGrantControllerMappingTests.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using System.Linq; + using Alethic.Auth0.Operator.Controllers; using Alethic.Auth0.Operator.Core.Models.ClientGrant.V1; -using Auth0.ManagementApi.Models; +using Auth0.ManagementApi; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -17,18 +19,24 @@ public class V1ClientGrantControllerMappingTests // ──────────────────────── FromApi OrganizationUsage ────────────────────── [TestMethod] - [DataRow(OrganizationUsage.Deny, V1ClientGrantOrganizationUsage.Deny)] - [DataRow(OrganizationUsage.Allow, V1ClientGrantOrganizationUsage.Allow)] - [DataRow(OrganizationUsage.Require, V1ClientGrantOrganizationUsage.Require)] - public void FromApi_OrganizationUsage_MapsCorrectly(OrganizationUsage input, V1ClientGrantOrganizationUsage expected) + public void FromApi_OrganizationUsage_Deny() + { + Assert.AreEqual(V1ClientGrantOrganizationUsage.Deny, V1ClientGrantController.FromApi(new ClientGrantOrganizationUsageEnum(ClientGrantOrganizationUsageEnum.Values.Deny))); + } + + [TestMethod] + public void FromApi_OrganizationUsage_Allow() { - Assert.AreEqual(expected, V1ClientGrantController.FromApi((OrganizationUsage?)input)); + Assert.AreEqual(V1ClientGrantOrganizationUsage.Allow, V1ClientGrantController.FromApi(new ClientGrantOrganizationUsageEnum(ClientGrantOrganizationUsageEnum.Values.Allow))); } + [TestMethod] + public void FromApi_OrganizationUsage_Require() => Assert.AreEqual(V1ClientGrantOrganizationUsage.Require, V1ClientGrantController.FromApi(new ClientGrantOrganizationUsageEnum(ClientGrantOrganizationUsageEnum.Values.Require))); + [TestMethod] public void FromApi_OrganizationUsage_Null_Returns_Null() { - Assert.IsNull(V1ClientGrantController.FromApi((OrganizationUsage?)null)); + Assert.IsNull(V1ClientGrantController.FromApi((ClientGrantOrganizationUsageEnum?)null)); } // ──────────────────────── FromApi ClientGrant ──────────────────────────── @@ -36,16 +44,16 @@ public void FromApi_OrganizationUsage_Null_Returns_Null() [TestMethod] public void FromApi_ClientGrant_Null_Returns_Null() { - Assert.IsNull(V1ClientGrantController.FromApi((ClientGrant?)null)); + Assert.IsNull(V1ClientGrantController.FromApi((GetClientGrantResponseContent?)null)); } [TestMethod] public void FromApi_ClientGrant_MapsScalarProperties() { - var source = new ClientGrant + var source = new GetClientGrantResponseContent { AllowAnyOrganization = true, - OrganizationUsage = OrganizationUsage.Allow, + OrganizationUsage = new ClientGrantOrganizationUsageEnum(ClientGrantOrganizationUsageEnum.Values.Allow), Scope = new List { "read:users", "write:users" }, }; @@ -60,7 +68,7 @@ public void FromApi_ClientGrant_MapsScalarProperties() [TestMethod] public void FromApi_ClientGrant_NullScope_ProducesNullScope() { - var source = new ClientGrant { Scope = null }; + var source = new GetClientGrantResponseContent { Scope = null }; var result = V1ClientGrantController.FromApi(source); Assert.IsNotNull(result); Assert.IsNull(result.Scope); @@ -69,7 +77,7 @@ public void FromApi_ClientGrant_NullScope_ProducesNullScope() [TestMethod] public void FromApi_ClientGrant_ClientRef_IsNull() { - var source = new ClientGrant { ClientId = "some-client-id" }; + var source = new GetClientGrantResponseContent { ClientId = "some-client-id" }; var result = V1ClientGrantController.FromApi(source); Assert.IsNotNull(result); Assert.IsNull(result.ClientRef); @@ -78,7 +86,7 @@ public void FromApi_ClientGrant_ClientRef_IsNull() [TestMethod] public void FromApi_ClientGrant_Audience_IsNull() { - var source = new ClientGrant { Audience = "https://api.example.com/" }; + var source = new GetClientGrantResponseContent { Audience = "https://api.example.com/" }; var result = V1ClientGrantController.FromApi(source); Assert.IsNotNull(result); Assert.IsNull(result.Audience); @@ -87,13 +95,11 @@ public void FromApi_ClientGrant_Audience_IsNull() // ──────────────────────── ToApi OrganizationUsage ──────────────────────── [TestMethod] - [DataRow(V1ClientGrantOrganizationUsage.Deny, OrganizationUsage.Deny)] - [DataRow(V1ClientGrantOrganizationUsage.Allow, OrganizationUsage.Allow)] - [DataRow(V1ClientGrantOrganizationUsage.Require, OrganizationUsage.Require)] - public void ToApi_OrganizationUsage_MapsCorrectly(V1ClientGrantOrganizationUsage input, OrganizationUsage expected) - { - Assert.AreEqual(expected, V1ClientGrantController.ToApi((V1ClientGrantOrganizationUsage?)input)); - } + public void ToApi_OrganizationUsage_Deny() => Assert.AreEqual(ClientGrantOrganizationUsageEnum.Values.Deny, V1ClientGrantController.ToApi((V1ClientGrantOrganizationUsage?)V1ClientGrantOrganizationUsage.Deny)?.Value); + [TestMethod] + public void ToApi_OrganizationUsage_Allow() => Assert.AreEqual(ClientGrantOrganizationUsageEnum.Values.Allow, V1ClientGrantController.ToApi((V1ClientGrantOrganizationUsage?)V1ClientGrantOrganizationUsage.Allow)?.Value); + [TestMethod] + public void ToApi_OrganizationUsage_Require() => Assert.AreEqual(ClientGrantOrganizationUsageEnum.Values.Require, V1ClientGrantController.ToApi((V1ClientGrantOrganizationUsage?)V1ClientGrantOrganizationUsage.Require)?.Value); [TestMethod] public void ToApi_OrganizationUsage_Null_Returns_Null() @@ -104,14 +110,19 @@ public void ToApi_OrganizationUsage_Null_Returns_Null() // ──────────────────────── Roundtrip OrganizationUsage ──────────────────── [TestMethod] - [DataRow(V1ClientGrantOrganizationUsage.Deny)] - [DataRow(V1ClientGrantOrganizationUsage.Allow)] - [DataRow(V1ClientGrantOrganizationUsage.Require)] - public void Roundtrip_OrganizationUsage(V1ClientGrantOrganizationUsage value) + public void Roundtrip_OrganizationUsage_Deny() + { + var api = V1ClientGrantController.ToApi((V1ClientGrantOrganizationUsage?)V1ClientGrantOrganizationUsage.Deny); var back = V1ClientGrantController.FromApi(api); Assert.AreEqual(V1ClientGrantOrganizationUsage.Deny, back); + } + [TestMethod] + public void Roundtrip_OrganizationUsage_Allow() + { + var api = V1ClientGrantController.ToApi((V1ClientGrantOrganizationUsage?)V1ClientGrantOrganizationUsage.Allow); var back = V1ClientGrantController.FromApi(api); Assert.AreEqual(V1ClientGrantOrganizationUsage.Allow, back); + } + [TestMethod] + public void Roundtrip_OrganizationUsage_Require() { - var api = V1ClientGrantController.ToApi((V1ClientGrantOrganizationUsage?)value); - var back = V1ClientGrantController.FromApi(api); - Assert.AreEqual(value, back); + var api = V1ClientGrantController.ToApi((V1ClientGrantOrganizationUsage?)V1ClientGrantOrganizationUsage.Require); var back = V1ClientGrantController.FromApi(api); Assert.AreEqual(V1ClientGrantOrganizationUsage.Require, back); } // ──────────────────────── ApplyToApi ───────────────────────────────────── @@ -126,12 +137,12 @@ public void ApplyToApi_CreateRequest_MapsAllFields() OrganizationUsage = V1ClientGrantOrganizationUsage.Deny, }; - var req = new ClientGrantCreateRequest(); + var req = new CreateClientGrantRequestContent { ClientId = "client-id", Audience = "https://api.example.com" }; V1ClientGrantController.ApplyToApi(conf, req); - CollectionAssert.AreEqual(new[] { "read:users", "write:users" }, req.Scope); + CollectionAssert.AreEqual(new[] { "read:users", "write:users" }, req.Scope?.ToArray()); Assert.AreEqual(false, req.AllowAnyOrganization); - Assert.AreEqual(OrganizationUsage.Deny, req.OrganizationUsage); + Assert.AreEqual(ClientGrantOrganizationUsageEnum.Values.Deny, req.OrganizationUsage?.Value); } [TestMethod] @@ -144,21 +155,21 @@ public void ApplyToApi_UpdateRequest_MapsAllFields() OrganizationUsage = V1ClientGrantOrganizationUsage.Require, }; - var req = new ClientGrantUpdateRequest(); + var req = new UpdateClientGrantRequestContent(); V1ClientGrantController.ApplyToApi(conf, req); - CollectionAssert.AreEqual(new[] { "openid" }, req.Scope); - Assert.AreEqual(true, req.AllowAnyOrganization); - Assert.AreEqual(OrganizationUsage.Require, req.OrganizationUsage); + CollectionAssert.AreEqual(new[] { "openid" }, req.Scope.Value?.ToArray()); + Assert.AreEqual(true, req.AllowAnyOrganization.Value); + Assert.AreEqual(ClientGrantOrganizationNullableUsageEnum.Values.Require, req.OrganizationUsage.Value?.Value); } [TestMethod] public void ApplyToApi_NullOrganizationUsage_LeavesNull() { var conf = new V1ClientGrantConf { OrganizationUsage = null }; - var req = new ClientGrantUpdateRequest(); + var req = new UpdateClientGrantRequestContent(); V1ClientGrantController.ApplyToApi(conf, req); - Assert.IsNull(req.OrganizationUsage); + Assert.IsFalse(req.OrganizationUsage.IsDefined); } } diff --git a/src/Alethic.Auth0.Operator.Tests/V1ConnectionControllerMappingTests.cs b/src/Alethic.Auth0.Operator.Tests/V1ConnectionControllerMappingTests.cs deleted file mode 100644 index b35d0db..0000000 --- a/src/Alethic.Auth0.Operator.Tests/V1ConnectionControllerMappingTests.cs +++ /dev/null @@ -1,239 +0,0 @@ -using Alethic.Auth0.Operator.Controllers; -using Alethic.Auth0.Operator.Core.Models.Connection.V1; - -using Auth0.ManagementApi.Models; - -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Alethic.Auth0.Operator.Tests -{ - - [TestClass] - public class V1ConnectionControllerMappingTests - { - - [TestMethod] - public void FromApi_Null_ReturnsNull() - { - Assert.IsNull(V1ConnectionController.FromApi((Connection?)null)); - } - - [TestMethod] - public void FromApi_Connection_MapsScalarProperties() - { - var source = new Connection - { - Name = "test-conn", - DisplayName = "Test Connection", - Strategy = "auth0", - Realms = ["realm1", "realm2"], - IsDomainConnection = true, - ShowAsButton = false, - ProvisioningTicketUrl = "https://example.com/ticket", - }; - - var result = V1ConnectionController.FromApi(source); - - Assert.IsNotNull(result); - Assert.AreEqual("test-conn", result.Name); - Assert.AreEqual("Test Connection", result.DisplayName); - Assert.AreEqual("auth0", result.Strategy); - CollectionAssert.AreEqual(new[] { "realm1", "realm2" }, result.Realms); - Assert.AreEqual(true, result.IsDomainConnection); - Assert.AreEqual(false, result.ShowAsButton); - Assert.AreEqual("https://example.com/ticket", result.ProvisioningTicketUrl); - } - - [TestMethod] - public void FromApi_Connection_EnabledClientsIsNull() - { - var result = V1ConnectionController.FromApi(new Connection { Name = "x", Strategy = "auth0" }); - Assert.IsNotNull(result); - Assert.IsNull(result.EnabledClients); - } - - [TestMethod] - public void FromApi_Connection_NullOptionsAndMetadata_MapsNull() - { - var result = V1ConnectionController.FromApi(new Connection { Name = "x", Strategy = "auth0" }); - Assert.IsNotNull(result); - Assert.IsNull(result.Options); - Assert.IsNull(result.Metadata); - } - - [TestMethod] - public void FromApiOptions_Null_ReturnsNull() - { - Assert.IsNull(V1ConnectionController.FromApiOptions(null, "auth0")); - Assert.IsNull(V1ConnectionController.FromApiOptions(null, "oidc")); - Assert.IsNull(V1ConnectionController.FromApiOptions(null, null)); - } - - [TestMethod] - public void FromApiOptions_Auth0Strategy_MapsTypedProperties() - { - var result = V1ConnectionController.FromApiOptions(new { passwordPolicy = "good" }, "auth0"); - Assert.IsNotNull(result); - Assert.AreEqual(V1ConnectionOptionsPasswordPolicy.Good, result.PasswordPolicy); - Assert.IsNull(result.AdditionalProperties); - } - - [TestMethod] - public void FromApiOptions_OtherStrategy_CapturesAsAdditionalProperties() - { - var result = V1ConnectionController.FromApiOptions(new { clientId = "abc", tenant = "mytenant" }, "oidc"); - Assert.IsNotNull(result); - Assert.IsNull(result.PasswordPolicy); - Assert.IsNotNull(result.AdditionalProperties); - Assert.AreEqual("abc", result.AdditionalProperties["clientId"]?.ToString()); - Assert.AreEqual("mytenant", result.AdditionalProperties["tenant"]?.ToString()); - } - - [TestMethod] - public void FromApiOptions_NullStrategy_CapturesAsAdditionalProperties() - { - var result = V1ConnectionController.FromApiOptions(new { foo = "bar" }, null); - Assert.IsNotNull(result); - Assert.IsNotNull(result.AdditionalProperties); - Assert.AreEqual("bar", result.AdditionalProperties["foo"]?.ToString()); - } - - [TestMethod] - public void FromApi_Connection_Auth0Strategy_MapsOptionsTyped() - { - var source = new Connection - { - Name = "x", - Strategy = "auth0", - Options = new { passwordPolicy = "good" }, - }; - - var result = V1ConnectionController.FromApi(source); - Assert.IsNotNull(result); - Assert.IsNotNull(result.Options); - Assert.AreEqual(V1ConnectionOptionsPasswordPolicy.Good, result.Options.PasswordPolicy); - Assert.IsNull(result.Options.AdditionalProperties); - } - - [TestMethod] - public void FromApi_Connection_OtherStrategy_MapsOptionsAsAdditionalProperties() - { - var source = new Connection - { - Name = "x", - Strategy = "oidc", - Options = new { clientId = "abc" }, - }; - - var result = V1ConnectionController.FromApi(source); - Assert.IsNotNull(result); - Assert.IsNotNull(result.Options); - Assert.IsNull(result.Options.PasswordPolicy); - Assert.IsNotNull(result.Options.AdditionalProperties); - Assert.AreEqual("abc", result.Options.AdditionalProperties["clientId"]?.ToString()); - } - - [TestMethod] - public void FromApi_Connection_MapsMetadata() - { - var source = new Connection - { - Name = "x", - Strategy = "auth0", - Metadata = new { env = "prod" }, - }; - - var result = V1ConnectionController.FromApi(source); - Assert.IsNotNull(result); - Assert.IsNotNull(result.Metadata); - Assert.AreEqual("prod", result.Metadata["env"]?.ToString()); - } - - [TestMethod] - public void FromApi_Connection_NullStrategy_MapsNull() - { - var result = V1ConnectionController.FromApi(new Connection { Name = "no-strat" }); - Assert.IsNotNull(result); - Assert.IsNull(result.Strategy); - } - - [TestMethod] - public void ApplyToApi_ConnectionBase_MapsName() - { - var conf = new V1ConnectionConf { Name = "my-conn" }; - var req = new ConnectionCreateRequest { Strategy = "auth0" }; - V1ConnectionController.ApplyToApi(conf, req); - Assert.AreEqual("my-conn", req.Name); - } - - [TestMethod] - public void ApplyToApi_ConnectionBase_MapsDisplayName() - { - var conf = new V1ConnectionConf { DisplayName = "My Conn" }; - var req = new ConnectionCreateRequest { Strategy = "auth0" }; - V1ConnectionController.ApplyToApi(conf, req); - Assert.AreEqual("My Conn", req.DisplayName); - } - - [TestMethod] - public void ApplyToApi_ConnectionBase_MapsRealms() - { - var conf = new V1ConnectionConf { Realms = ["r1"] }; - var req = new ConnectionCreateRequest { Strategy = "auth0" }; - V1ConnectionController.ApplyToApi(conf, req); - CollectionAssert.AreEqual(new[] { "r1" }, req.Realms); - } - - [TestMethod] - public void ApplyToApi_ConnectionBase_MapsIsDomainConnection() - { - var conf = new V1ConnectionConf { IsDomainConnection = true }; - var req = new ConnectionCreateRequest { Strategy = "auth0" }; - V1ConnectionController.ApplyToApi(conf, req); - Assert.AreEqual(true, req.IsDomainConnection); - } - - [TestMethod] - public void ApplyToApi_ConnectionBase_MapsShowAsButton() - { - var conf = new V1ConnectionConf { ShowAsButton = true }; - var req = new ConnectionCreateRequest { Strategy = "auth0" }; - V1ConnectionController.ApplyToApi(conf, req); - Assert.AreEqual(true, req.ShowAsButton); - } - - [TestMethod] - public void ApplyToApi_ConnectionBase_NullFieldsLeaveTargetUnchanged() - { - var conf = new V1ConnectionConf(); - var req = new ConnectionCreateRequest { Strategy = "auth0", Name = "original" }; - V1ConnectionController.ApplyToApi(conf, req); - Assert.AreEqual("original", req.Name); - } - - [TestMethod] - public void Roundtrip_ScalarProperties() - { - var source = new Connection - { - Name = "roundtrip", - DisplayName = "Roundtrip", - Strategy = "auth0", - IsDomainConnection = false, - ShowAsButton = true, - ProvisioningTicketUrl = "https://ticket", - }; - - var conf = V1ConnectionController.FromApi(source)!; - var req = new ConnectionCreateRequest { Strategy = conf.Strategy! }; - V1ConnectionController.ApplyToApi(conf, req); - - Assert.AreEqual(source.Name, req.Name); - Assert.AreEqual(source.DisplayName, req.DisplayName); - Assert.AreEqual(source.IsDomainConnection, req.IsDomainConnection); - Assert.AreEqual(source.ShowAsButton, req.ShowAsButton); - } - - } - -} diff --git a/src/Alethic.Auth0.Operator.Tests/V1ResourceServerControllerMappingTests.cs b/src/Alethic.Auth0.Operator.Tests/V1ResourceServerControllerMappingTests.cs index 35711f4..b675851 100644 --- a/src/Alethic.Auth0.Operator.Tests/V1ResourceServerControllerMappingTests.cs +++ b/src/Alethic.Auth0.Operator.Tests/V1ResourceServerControllerMappingTests.cs @@ -1,7 +1,9 @@ +using System.Linq; + using Alethic.Auth0.Operator.Controllers; using Alethic.Auth0.Operator.Core.Models.ResourceServer.V1; -using Auth0.ManagementApi.Models; +using Auth0.ManagementApi; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -29,43 +31,25 @@ public void FromApi_ResourceServerScope_Null_Returns_Null() [TestMethod] public void FromApi_SigningAlgorithm_Null_Returns_Null() { - Assert.IsNull(V1ResourceServerController.FromApi((SigningAlgorithm?)null)); - } - - [TestMethod] - public void FromApi_TokenDialect_Null_Returns_Null() - { - Assert.IsNull(V1ResourceServerController.FromApi((TokenDialect?)null)); - } - - [TestMethod] - public void FromApi_ConsentPolicy_Null_Returns_Null() - { - Assert.IsNull(V1ResourceServerController.FromApi((ConsentPolicy?)null)); - } - - [TestMethod] - public void FromApi_AuthorizationDetail_Null_Returns_Null() - { - Assert.IsNull(V1ResourceServerController.FromApi((ResourceServerAuthorizationDetail?)null)); + Assert.IsNull(V1ResourceServerController.FromApi((SigningAlgorithmEnum?)null)); } [TestMethod] public void FromApi_TokenEncryption_Null_Returns_Null() { - Assert.IsNull(V1ResourceServerController.FromApi((TokenEncryption?)null)); + Assert.IsNull(V1ResourceServerController.FromApi((ResourceServerTokenEncryption?)null)); } [TestMethod] public void FromApi_TokenEncryptionKey_Null_Returns_Null() { - Assert.IsNull(V1ResourceServerController.FromApi((TokenEncryptionKey?)null)); + Assert.IsNull(V1ResourceServerController.FromApi((ResourceServerTokenEncryptionKey?)null)); } [TestMethod] public void FromApi_ProofOfPossession_Null_Returns_Null() { - Assert.IsNull(V1ResourceServerController.FromApi((ProofOfPossession?)null)); + Assert.IsNull(V1ResourceServerController.FromApi((ResourceServerProofOfPossession?)null)); } // ──────────────────────── FromApi property-mapping tests ──────────────────────── @@ -83,7 +67,6 @@ public void FromApi_ResourceServer_MapsScalarProperties() TokenLifetimeForWeb = 7200, AllowOfflineAccess = true, SkipConsentForVerifiableFirstPartyClients = false, - VerificationLocation = "https://verify.example.com", EnforcePolicies = true, }; @@ -97,7 +80,6 @@ public void FromApi_ResourceServer_MapsScalarProperties() Assert.AreEqual(7200, result.TokenLifetimeForWeb); Assert.IsTrue(result.AllowOfflineAccess); Assert.IsFalse(result.SkipConsentForVerifiableFirstPartyClients); - Assert.AreEqual("https://verify.example.com", result.VerificationLocation); Assert.IsTrue(result.EnforcePolicies); } @@ -121,32 +103,22 @@ public void FromApi_ResourceServer_MapsScopes() var result = V1ResourceServerController.FromApi(source)!; - Assert.AreEqual(2, result.Scopes!.Count); + Assert.AreEqual(2, result.Scopes!.Length); Assert.AreEqual("read:data", result.Scopes[0].Value); Assert.AreEqual("write:data", result.Scopes[1].Value); } - [TestMethod] - public void FromApi_AuthorizationDetail_MapsType() - { - var result = V1ResourceServerController.FromApi(new ResourceServerAuthorizationDetail { Type = "payment_initiation" })!; - - Assert.AreEqual("payment_initiation", result.Type); - } - [TestMethod] public void FromApi_TokenEncryptionKey_MapsProperties() { - var result = V1ResourceServerController.FromApi(new TokenEncryptionKey + var result = V1ResourceServerController.FromApi(new ResourceServerTokenEncryptionKey { Name = "mykey", - Algorithm = "RSA-OAEP", Kid = "kid-1", Pem = "-----BEGIN PUBLIC KEY-----", })!; Assert.AreEqual("mykey", result.Name); - Assert.AreEqual("RSA-OAEP", result.Algorithm); Assert.AreEqual("kid-1", result.Kid); Assert.AreEqual("-----BEGIN PUBLIC KEY-----", result.Pem); } @@ -154,10 +126,10 @@ public void FromApi_TokenEncryptionKey_MapsProperties() [TestMethod] public void FromApi_TokenEncryption_MapsFormatAndKey() { - var result = V1ResourceServerController.FromApi(new TokenEncryption + var result = V1ResourceServerController.FromApi(new ResourceServerTokenEncryption { - Format = TokenFormat.CompactNestedJwe, - EncryptionKey = new TokenEncryptionKey { Name = "k1" }, + Format = new ResourceServerTokenEncryptionFormatEnum(ResourceServerTokenEncryptionFormatEnum.Values.CompactNestedJwe), + EncryptionKey = new ResourceServerTokenEncryptionKey { Name = "k1" }, })!; Assert.AreEqual(V1ResourceServerTokenFormat.CompactNestedJwe, result.Format); @@ -167,98 +139,137 @@ public void FromApi_TokenEncryption_MapsFormatAndKey() [TestMethod] public void FromApi_ProofOfPossession_MapsProperties() { - var result = V1ResourceServerController.FromApi(new ProofOfPossession + var result = V1ResourceServerController.FromApi(new ResourceServerProofOfPossession { Required = true, - Mechanism = Mechanism.Mtls, + Mechanism = new ResourceServerProofOfPossessionMechanismEnum(ResourceServerProofOfPossessionMechanismEnum.Values.Mtls), })!; Assert.IsTrue(result.Required); Assert.AreEqual(V1ResourceServerMechanism.Mtls, result.Mechanism); } - // ──────────────────────── FromApi enum tests ──────────────────────── - [TestMethod] - [DataRow(SigningAlgorithm.HS256, V1ResourceServerSigningAlgorithm.HS256)] - [DataRow(SigningAlgorithm.RS256, V1ResourceServerSigningAlgorithm.RS256)] - [DataRow(SigningAlgorithm.PS256, V1ResourceServerSigningAlgorithm.PS256)] - public void FromApi_SigningAlgorithm_MapsCorrectly(SigningAlgorithm input, V1ResourceServerSigningAlgorithm expected) + public void FromApi_ResourceServer_MapsNewRequestBackedProperties() { - Assert.AreEqual(expected, V1ResourceServerController.FromApi((SigningAlgorithm?)input)); + var source = new ResourceServer + { + Identifier = "https://api.example.com", + AllowOnlineAccess = true, + AllowOnlineAccessWithEphemeralSessions = false, + AuthorizationPolicy = new ResourceServerAuthorizationPolicy { PolicyId = "pol_123" }, + SubjectTypeAuthorization = new ResourceServerSubjectTypeAuthorization + { + Client = new ResourceServerSubjectTypeAuthorizationClient + { + Policy = new ResourceServerSubjectTypeAuthorizationClientPolicyEnum(ResourceServerSubjectTypeAuthorizationClientPolicyEnum.Values.RequireClientGrant), + }, + User = new ResourceServerSubjectTypeAuthorizationUser + { + Policy = new ResourceServerSubjectTypeAuthorizationUserPolicyEnum(ResourceServerSubjectTypeAuthorizationUserPolicyEnum.Values.AllowAll), + }, + }, + }; + + var result = V1ResourceServerController.FromApi(source)!; + + Assert.IsTrue(result.AllowOnlineAccess); + Assert.IsFalse(result.AllowOnlineAccessWithEphemeralSessions); + Assert.AreEqual("pol_123", result.AuthorizationPolicy!.PolicyId); + Assert.AreEqual(V1ResourceServerSubjectTypeAuthorizationClientPolicy.RequireClientGrant, result.SubjectTypeAuthorization!.Client!.Policy); + Assert.AreEqual(V1ResourceServerSubjectTypeAuthorizationUserPolicy.AllowAll, result.SubjectTypeAuthorization.User!.Policy); } + // ──────────────────────── FromApi enum tests ──────────────────────── + [TestMethod] - [DataRow(TokenDialect.AccessToken, V1ResourceServerTokenDialect.AccessToken)] - [DataRow(TokenDialect.AccessTokenAuthZ, V1ResourceServerTokenDialect.AccessTokenAuthZ)] - [DataRow(TokenDialect.Rfc9068Profile, V1ResourceServerTokenDialect.Rfc9068Profile)] - [DataRow(TokenDialect.Rfc9068ProfileAuthz, V1ResourceServerTokenDialect.Rfc9068ProfileAuthz)] - public void FromApi_TokenDialect_MapsCorrectly(TokenDialect input, V1ResourceServerTokenDialect expected) - { - Assert.AreEqual(expected, V1ResourceServerController.FromApi((TokenDialect?)input)); - } + public void FromApi_SigningAlgorithm_Hs256() => Assert.AreEqual(V1ResourceServerSigningAlgorithm.HS256, V1ResourceServerController.FromApi(new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Hs256))); + [TestMethod] + public void FromApi_SigningAlgorithm_Rs256() => Assert.AreEqual(V1ResourceServerSigningAlgorithm.RS256, V1ResourceServerController.FromApi(new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Rs256))); + [TestMethod] + public void FromApi_SigningAlgorithm_Ps256() => Assert.AreEqual(V1ResourceServerSigningAlgorithm.PS256, V1ResourceServerController.FromApi(new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Ps256))); + + [TestMethod] + public void FromApi_TokenDialect_AccessToken() => Assert.AreEqual(V1ResourceServerTokenDialect.AccessToken, V1ResourceServerController.FromApi(new ResourceServerTokenDialectResponseEnum(ResourceServerTokenDialectResponseEnum.Values.AccessToken))); + [TestMethod] + public void FromApi_TokenDialect_AccessTokenAuthz() => Assert.AreEqual(V1ResourceServerTokenDialect.AccessTokenAuthZ, V1ResourceServerController.FromApi(new ResourceServerTokenDialectResponseEnum(ResourceServerTokenDialectResponseEnum.Values.AccessTokenAuthz))); + [TestMethod] + public void FromApi_TokenDialect_Rfc9068Profile() => Assert.AreEqual(V1ResourceServerTokenDialect.Rfc9068Profile, V1ResourceServerController.FromApi(new ResourceServerTokenDialectResponseEnum(ResourceServerTokenDialectResponseEnum.Values.Rfc9068Profile))); + [TestMethod] + public void FromApi_TokenDialect_Rfc9068ProfileAuthz() => Assert.AreEqual(V1ResourceServerTokenDialect.Rfc9068ProfileAuthz, V1ResourceServerController.FromApi(new ResourceServerTokenDialectResponseEnum(ResourceServerTokenDialectResponseEnum.Values.Rfc9068ProfileAuthz))); [TestMethod] public void FromApi_ConsentPolicy_TransactionalAuthorizationWithMfa_MapsCorrectly() { Assert.AreEqual(V1ResourceServerConsentPolicy.TransactionalAuthorizationWithMfa, - V1ResourceServerController.FromApi((ConsentPolicy?)ConsentPolicy.TransactionalAuthorizationWithMfa)); + V1ResourceServerController.FromApi(new ResourceServerConsentPolicyEnum(ResourceServerConsentPolicyEnum.Values.TransactionalAuthorizationWithMfa))); } [TestMethod] public void FromApi_TokenFormat_CompactNestedJwe_MapsCorrectly() { Assert.AreEqual(V1ResourceServerTokenFormat.CompactNestedJwe, - V1ResourceServerController.FromApi(TokenFormat.CompactNestedJwe)); + V1ResourceServerController.FromApi(new ResourceServerTokenEncryptionFormatEnum(ResourceServerTokenEncryptionFormatEnum.Values.CompactNestedJwe))); } [TestMethod] public void FromApi_Mechanism_Mtls_MapsCorrectly() { Assert.AreEqual(V1ResourceServerMechanism.Mtls, - V1ResourceServerController.FromApi(Mechanism.Mtls)); + V1ResourceServerController.FromApi(new ResourceServerProofOfPossessionMechanismEnum(ResourceServerProofOfPossessionMechanismEnum.Values.Mtls))); } - // ──────────────────────── ToApi enum tests ──────────────────────── - [TestMethod] - [DataRow(V1ResourceServerSigningAlgorithm.HS256, SigningAlgorithm.HS256)] - [DataRow(V1ResourceServerSigningAlgorithm.RS256, SigningAlgorithm.RS256)] - [DataRow(V1ResourceServerSigningAlgorithm.PS256, SigningAlgorithm.PS256)] - public void ToApi_SigningAlgorithm_MapsCorrectly(V1ResourceServerSigningAlgorithm input, SigningAlgorithm expected) + public void FromApi_Mechanism_Dpop_MapsCorrectly() { - Assert.AreEqual(expected, V1ResourceServerController.ToApi(input)); + Assert.AreEqual(V1ResourceServerMechanism.Dpop, + V1ResourceServerController.FromApi(new ResourceServerProofOfPossessionMechanismEnum(ResourceServerProofOfPossessionMechanismEnum.Values.Dpop))); } + // ──────────────────────── ToApi enum tests ──────────────────────── + [TestMethod] - [DataRow(V1ResourceServerTokenDialect.AccessToken, TokenDialect.AccessToken)] - [DataRow(V1ResourceServerTokenDialect.AccessTokenAuthZ, TokenDialect.AccessTokenAuthZ)] - [DataRow(V1ResourceServerTokenDialect.Rfc9068Profile, TokenDialect.Rfc9068Profile)] - [DataRow(V1ResourceServerTokenDialect.Rfc9068ProfileAuthz, TokenDialect.Rfc9068ProfileAuthz)] - public void ToApi_TokenDialect_MapsCorrectly(V1ResourceServerTokenDialect input, TokenDialect expected) - { - Assert.AreEqual(expected, V1ResourceServerController.ToApi(input)); - } + public void ToApi_SigningAlgorithm_Hs256() => Assert.AreEqual(SigningAlgorithmEnum.Values.Hs256, V1ResourceServerController.ToApi(V1ResourceServerSigningAlgorithm.HS256).Value); + [TestMethod] + public void ToApi_SigningAlgorithm_Rs256() => Assert.AreEqual(SigningAlgorithmEnum.Values.Rs256, V1ResourceServerController.ToApi(V1ResourceServerSigningAlgorithm.RS256).Value); + [TestMethod] + public void ToApi_SigningAlgorithm_Ps256() => Assert.AreEqual(SigningAlgorithmEnum.Values.Ps256, V1ResourceServerController.ToApi(V1ResourceServerSigningAlgorithm.PS256).Value); + + [TestMethod] + public void ToApi_TokenDialect_AccessToken() => Assert.AreEqual(ResourceServerTokenDialectSchemaEnum.Values.AccessToken, V1ResourceServerController.ToApi(V1ResourceServerTokenDialect.AccessToken).Value); + [TestMethod] + public void ToApi_TokenDialect_AccessTokenAuthz() => Assert.AreEqual(ResourceServerTokenDialectSchemaEnum.Values.AccessTokenAuthz, V1ResourceServerController.ToApi(V1ResourceServerTokenDialect.AccessTokenAuthZ).Value); + [TestMethod] + public void ToApi_TokenDialect_Rfc9068Profile() => Assert.AreEqual(ResourceServerTokenDialectSchemaEnum.Values.Rfc9068Profile, V1ResourceServerController.ToApi(V1ResourceServerTokenDialect.Rfc9068Profile).Value); + [TestMethod] + public void ToApi_TokenDialect_Rfc9068ProfileAuthz() => Assert.AreEqual(ResourceServerTokenDialectSchemaEnum.Values.Rfc9068ProfileAuthz, V1ResourceServerController.ToApi(V1ResourceServerTokenDialect.Rfc9068ProfileAuthz).Value); [TestMethod] public void ToApi_ConsentPolicy_TransactionalAuthorizationWithMfa_MapsCorrectly() { - Assert.AreEqual(ConsentPolicy.TransactionalAuthorizationWithMfa, - V1ResourceServerController.ToApi(V1ResourceServerConsentPolicy.TransactionalAuthorizationWithMfa)); + Assert.AreEqual(ResourceServerConsentPolicyEnum.Values.TransactionalAuthorizationWithMfa, + V1ResourceServerController.ToApi(V1ResourceServerConsentPolicy.TransactionalAuthorizationWithMfa).Value); } [TestMethod] public void ToApi_TokenFormat_CompactNestedJwe_MapsCorrectly() { - Assert.AreEqual(TokenFormat.CompactNestedJwe, - V1ResourceServerController.ToApi(V1ResourceServerTokenFormat.CompactNestedJwe)); + Assert.AreEqual(ResourceServerTokenEncryptionFormatEnum.Values.CompactNestedJwe, + V1ResourceServerController.ToApi(V1ResourceServerTokenFormat.CompactNestedJwe).Value); } [TestMethod] public void ToApi_Mechanism_Mtls_MapsCorrectly() { - Assert.AreEqual(Mechanism.Mtls, - V1ResourceServerController.ToApi(V1ResourceServerMechanism.Mtls)); + Assert.AreEqual(ResourceServerProofOfPossessionMechanismEnum.Values.Mtls, + V1ResourceServerController.ToApi(V1ResourceServerMechanism.Mtls).Value); + } + + [TestMethod] + public void ToApi_Mechanism_Dpop_MapsCorrectly() + { + Assert.AreEqual(ResourceServerProofOfPossessionMechanismEnum.Values.Dpop, + V1ResourceServerController.ToApi(V1ResourceServerMechanism.Dpop).Value); } [TestMethod] @@ -270,35 +281,50 @@ public void ToApi_Scope_MapsProperties() Assert.AreEqual("Read data", result.Description); } + // ──────────────────────── Roundtrip tests ──────────────────────── + [TestMethod] - public void ToApi_AuthorizationDetail_MapsType() + public void SigningAlgorithm_Roundtrip_Hs256() { - var result = V1ResourceServerController.ToApi(new V1ResourceServerAuthorizationDetail { Type = "payment_initiation" }); - - Assert.AreEqual("payment_initiation", result.Type); + var api = V1ResourceServerController.ToApi(V1ResourceServerSigningAlgorithm.HS256); + Assert.AreEqual(V1ResourceServerSigningAlgorithm.HS256, V1ResourceServerController.FromApi((SigningAlgorithmEnum?)api)); + } + [TestMethod] + public void SigningAlgorithm_Roundtrip_Rs256() + { + var api = V1ResourceServerController.ToApi(V1ResourceServerSigningAlgorithm.RS256); + Assert.AreEqual(V1ResourceServerSigningAlgorithm.RS256, V1ResourceServerController.FromApi((SigningAlgorithmEnum?)api)); } - - // ──────────────────────── Roundtrip tests ──────────────────────── - [TestMethod] - [DataRow(V1ResourceServerSigningAlgorithm.HS256)] - [DataRow(V1ResourceServerSigningAlgorithm.RS256)] - [DataRow(V1ResourceServerSigningAlgorithm.PS256)] - public void SigningAlgorithm_Roundtrip(V1ResourceServerSigningAlgorithm input) + public void SigningAlgorithm_Roundtrip_Ps256() { - var api = V1ResourceServerController.ToApi(input); - Assert.AreEqual(input, V1ResourceServerController.FromApi((SigningAlgorithm?)api)); + var api = V1ResourceServerController.ToApi(V1ResourceServerSigningAlgorithm.PS256); + Assert.AreEqual(V1ResourceServerSigningAlgorithm.PS256, V1ResourceServerController.FromApi((SigningAlgorithmEnum?)api)); } [TestMethod] - [DataRow(V1ResourceServerTokenDialect.AccessToken)] - [DataRow(V1ResourceServerTokenDialect.AccessTokenAuthZ)] - [DataRow(V1ResourceServerTokenDialect.Rfc9068Profile)] - [DataRow(V1ResourceServerTokenDialect.Rfc9068ProfileAuthz)] - public void TokenDialect_Roundtrip(V1ResourceServerTokenDialect input) + public void TokenDialect_Roundtrip_AccessToken() + { + var api = V1ResourceServerController.ToApi(V1ResourceServerTokenDialect.AccessToken); + Assert.AreEqual(V1ResourceServerTokenDialect.AccessToken, V1ResourceServerController.FromApi(new ResourceServerTokenDialectResponseEnum(api.Value))); + } + [TestMethod] + public void TokenDialect_Roundtrip_AccessTokenAuthZ() + { + var api = V1ResourceServerController.ToApi(V1ResourceServerTokenDialect.AccessTokenAuthZ); + Assert.AreEqual(V1ResourceServerTokenDialect.AccessTokenAuthZ, V1ResourceServerController.FromApi(new ResourceServerTokenDialectResponseEnum(api.Value))); + } + [TestMethod] + public void TokenDialect_Roundtrip_Rfc9068Profile() { - var api = V1ResourceServerController.ToApi(input); - Assert.AreEqual(input, V1ResourceServerController.FromApi((TokenDialect?)api)); + var api = V1ResourceServerController.ToApi(V1ResourceServerTokenDialect.Rfc9068Profile); + Assert.AreEqual(V1ResourceServerTokenDialect.Rfc9068Profile, V1ResourceServerController.FromApi(new ResourceServerTokenDialectResponseEnum(api.Value))); + } + [TestMethod] + public void TokenDialect_Roundtrip_Rfc9068ProfileAuthz() + { + var api = V1ResourceServerController.ToApi(V1ResourceServerTokenDialect.Rfc9068ProfileAuthz); + Assert.AreEqual(V1ResourceServerTokenDialect.Rfc9068ProfileAuthz, V1ResourceServerController.FromApi(new ResourceServerTokenDialectResponseEnum(api.Value))); } // ──────────────────────── ApplyToApi tests ──────────────────────── @@ -315,34 +341,48 @@ public void ApplyToApi_CreateRequest_MapsAllFields() TokenLifetime = 86400, TokenLifetimeForWeb = 7200, AllowOfflineAccess = true, + AllowOnlineAccess = true, + AllowOnlineAccessWithEphemeralSessions = false, SkipConsentForVerifiableFirstPartyClients = false, VerificationLocation = "https://verify.example.com", TokenDialect = V1ResourceServerTokenDialect.AccessToken, EnforcePolicies = true, ConsentPolicy = V1ResourceServerConsentPolicy.TransactionalAuthorizationWithMfa, Scopes = [new V1ResourceServerScope { Value = "read:data", Description = "Read" }], - AuthorizationDetails = [new V1ResourceServerAuthorizationDetail { Type = "payment_initiation" }], + AuthorizationPolicy = new V1ResourceServerAuthorizationPolicy { PolicyId = "pol_123" }, + SubjectTypeAuthorization = new V1ResourceServerSubjectTypeAuthorization + { + Client = new V1ResourceServerSubjectTypeAuthorizationClient + { + Policy = V1ResourceServerSubjectTypeAuthorizationClientPolicy.RequireClientGrant, + }, + User = new V1ResourceServerSubjectTypeAuthorizationUser + { + Policy = V1ResourceServerSubjectTypeAuthorizationUserPolicy.AllowAll, + }, + }, }; - var req = new ResourceServerCreateRequest(); + var req = new CreateResourceServerRequestContent { Identifier = "https://api.example.com" }; V1ResourceServerController.ApplyToApi(conf, req); Assert.AreEqual("https://api.example.com", req.Identifier); Assert.AreEqual("My API", req.Name); - Assert.AreEqual(SigningAlgorithm.RS256, req.SigningAlgorithm); + Assert.AreEqual(SigningAlgorithmEnum.Values.Rs256, req.SigningAlg?.Value); Assert.AreEqual("secret", req.SigningSecret); Assert.AreEqual(86400, req.TokenLifetime); - Assert.AreEqual(7200, req.TokenLifetimeForWeb); Assert.IsTrue(req.AllowOfflineAccess); + Assert.IsTrue(req.AllowOnlineAccess); + Assert.IsFalse(req.AllowOnlineAccessWithEphemeralSessions); Assert.IsFalse(req.SkipConsentForVerifiableFirstPartyClients); - Assert.AreEqual("https://verify.example.com", req.VerificationLocation); - Assert.AreEqual(TokenDialect.AccessToken, req.TokenDialect); + Assert.AreEqual(ResourceServerTokenDialectSchemaEnum.Values.AccessToken, req.TokenDialect?.Value); Assert.IsTrue(req.EnforcePolicies); - Assert.AreEqual(ConsentPolicy.TransactionalAuthorizationWithMfa, req.ConsentPolicy); - Assert.AreEqual(1, req.Scopes!.Count); - Assert.AreEqual("read:data", req.Scopes[0].Value); - Assert.AreEqual(1, req.AuthorizationDetails!.Count); - Assert.AreEqual("payment_initiation", req.AuthorizationDetails[0].Type); + Assert.AreEqual(ResourceServerConsentPolicyEnum.Values.TransactionalAuthorizationWithMfa, req.ConsentPolicy.Value?.Value); + Assert.AreEqual("pol_123", req.AuthorizationPolicy.Value!.PolicyId); + Assert.AreEqual(ResourceServerSubjectTypeAuthorizationClientPolicyEnum.Values.RequireClientGrant.ToString(), req.SubjectTypeAuthorization.Client!.Policy!.Value.ToString()); + Assert.AreEqual(ResourceServerSubjectTypeAuthorizationUserPolicyEnum.Values.AllowAll.ToString(), req.SubjectTypeAuthorization.User!.Policy!.Value.ToString()); + Assert.AreEqual(1, req.Scopes!.Count()); + Assert.AreEqual("read:data", req.Scopes.First().Value); } [TestMethod] @@ -350,7 +390,7 @@ public void ApplyToApi_UpdateRequest_DoesNotSetIdentifier() { var conf = new V1ResourceServerConf { Identifier = "https://api.example.com", Name = "My API" }; - var req = new ResourceServerUpdateRequest(); + var req = new UpdateResourceServerRequestContent(); V1ResourceServerController.ApplyToApi(conf, req); Assert.AreEqual("My API", req.Name); @@ -374,14 +414,13 @@ public void ApplyToApi_TokenEncryption_MapsCorrectly() }, }; - var req = new ResourceServerCreateRequest(); + var req = new CreateResourceServerRequestContent { Identifier = "https://api.example.com" }; V1ResourceServerController.ApplyToApi(conf, req); - Assert.AreEqual(TokenFormat.CompactNestedJwe, req.TokenEncryption!.Format); - Assert.AreEqual("mykey", req.TokenEncryption.EncryptionKey!.Name); - Assert.AreEqual("RSA-OAEP", req.TokenEncryption.EncryptionKey.Algorithm); - Assert.AreEqual("kid-1", req.TokenEncryption.EncryptionKey.Kid); - Assert.AreEqual("pem-data", req.TokenEncryption.EncryptionKey.Pem); + Assert.AreEqual(ResourceServerTokenEncryptionFormatEnum.Values.CompactNestedJwe, req.TokenEncryption.Value!.Format.Value); + Assert.AreEqual("mykey", req.TokenEncryption.Value!.EncryptionKey!.Name); + Assert.AreEqual("kid-1", req.TokenEncryption.Value!.EncryptionKey!.Kid); + Assert.AreEqual("pem-data", req.TokenEncryption.Value!.EncryptionKey!.Pem); } [TestMethod] @@ -396,11 +435,9 @@ public void ApplyToApi_ProofOfPossession_MapsCorrectly() }, }; - var req = new ResourceServerCreateRequest(); + var req = new CreateResourceServerRequestContent { Identifier = "https://api.example.com" }; V1ResourceServerController.ApplyToApi(conf, req); - - Assert.IsTrue(req.ProofOfPossession!.Required); - Assert.AreEqual(Mechanism.Mtls, req.ProofOfPossession.Mechanism); + Assert.AreEqual(ResourceServerProofOfPossessionMechanismEnum.Values.Mtls, req.ProofOfPossession.Value!.Mechanism.Value); } [TestMethod] @@ -408,16 +445,14 @@ public void ApplyToApi_NullOptionalFields_DoesNotOverwrite() { var conf = new V1ResourceServerConf { Name = "My API" }; - var req = new ResourceServerCreateRequest(); + var req = new CreateResourceServerRequestContent { Identifier = "https://api.example.com" }; V1ResourceServerController.ApplyToApi(conf, req); - - Assert.IsNull(req.SigningAlgorithm); Assert.IsNull(req.TokenDialect); - Assert.IsNull(req.ConsentPolicy); - Assert.IsNull(req.TokenEncryption); - Assert.IsNull(req.ProofOfPossession); + Assert.IsFalse(req.ConsentPolicy.IsDefined); + Assert.IsFalse(req.TokenEncryption.IsDefined); + Assert.IsFalse(req.ProofOfPossession.IsDefined); Assert.IsNull(req.Scopes); - Assert.IsNull(req.AuthorizationDetails); + Assert.IsFalse(req.AuthorizationDetails.IsDefined); } } diff --git a/src/Alethic.Auth0.Operator.Tests/V1alpha1BrandingThemeControllerMappingTests.cs b/src/Alethic.Auth0.Operator.Tests/V1alpha1BrandingThemeControllerMappingTests.cs index f38fef4..940fdaf 100644 --- a/src/Alethic.Auth0.Operator.Tests/V1alpha1BrandingThemeControllerMappingTests.cs +++ b/src/Alethic.Auth0.Operator.Tests/V1alpha1BrandingThemeControllerMappingTests.cs @@ -1,7 +1,7 @@ using Alethic.Auth0.Operator.Controllers; using Alethic.Auth0.Operator.Core.Models.BrandingTheme.V1alpha1; -using Auth0.ManagementApi.Models; +using Auth0.ManagementApi; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -15,206 +15,198 @@ public class V1alpha1BrandingThemeControllerMappingTests // ──────────────────────── ToApi CaptchaWidgetTheme ──────────────────────── [TestMethod] - [DataRow(V1alpha1BrandingThemeCaptchaWidgetTheme.Light, CaptchaWidgetTheme.Light)] - [DataRow(V1alpha1BrandingThemeCaptchaWidgetTheme.Dark, CaptchaWidgetTheme.Dark)] - [DataRow(V1alpha1BrandingThemeCaptchaWidgetTheme.Auto, CaptchaWidgetTheme.Auto)] - public void ToApi_CaptchaWidgetTheme_MapsCorrectly(V1alpha1BrandingThemeCaptchaWidgetTheme input, CaptchaWidgetTheme expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.ToApi(input)); - } + public void ToApi_CaptchaWidgetTheme_Light() => Assert.AreEqual(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Light, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeCaptchaWidgetTheme.Light).Value); + + [TestMethod] + public void ToApi_CaptchaWidgetTheme_Dark() => Assert.AreEqual(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Dark, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeCaptchaWidgetTheme.Dark).Value); + + [TestMethod] + public void ToApi_CaptchaWidgetTheme_Auto() => Assert.AreEqual(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Auto, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeCaptchaWidgetTheme.Auto).Value); // ──────────────────────── ToApi SocialButtonsLayout ─────────────────────── [TestMethod] - [DataRow(V1alpha1BrandingThemeSocialButtonsLayout.Top, SocialButtonsLayout.Top)] - [DataRow(V1alpha1BrandingThemeSocialButtonsLayout.Bottom, SocialButtonsLayout.Bottom)] - public void ToApi_SocialButtonsLayout_MapsCorrectly(V1alpha1BrandingThemeSocialButtonsLayout input, SocialButtonsLayout expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.ToApi(input)); - } + public void ToApi_SocialButtonsLayout_Top() => Assert.AreEqual(BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Top, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeSocialButtonsLayout.Top).Value); + + [TestMethod] + public void ToApi_SocialButtonsLayout_Bottom() => Assert.AreEqual(BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Bottom, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeSocialButtonsLayout.Bottom).Value); // ──────────────────────── ToApi LogoPosition ────────────────────────────── [TestMethod] - [DataRow(V1alpha1BrandingThemeLogoPosition.Center, LogoPosition.Center)] - [DataRow(V1alpha1BrandingThemeLogoPosition.Left, LogoPosition.Left)] - [DataRow(V1alpha1BrandingThemeLogoPosition.Right, LogoPosition.Right)] - [DataRow(V1alpha1BrandingThemeLogoPosition.None, LogoPosition.None)] - public void ToApi_LogoPosition_MapsCorrectly(V1alpha1BrandingThemeLogoPosition input, LogoPosition expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.ToApi(input)); - } + public void ToApi_LogoPosition_Center() => Assert.AreEqual(BrandingThemeWidgetLogoPositionEnum.Values.Center, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeLogoPosition.Center).Value); + + [TestMethod] + public void ToApi_LogoPosition_Left() => Assert.AreEqual(BrandingThemeWidgetLogoPositionEnum.Values.Left, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeLogoPosition.Left).Value); + + [TestMethod] + public void ToApi_LogoPosition_Right() => Assert.AreEqual(BrandingThemeWidgetLogoPositionEnum.Values.Right, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeLogoPosition.Right).Value); + + [TestMethod] + public void ToApi_LogoPosition_None() => Assert.AreEqual(BrandingThemeWidgetLogoPositionEnum.Values.None, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeLogoPosition.None).Value); // ──────────────────────── ToApi HeaderTextAlignment ─────────────────────── [TestMethod] - [DataRow(V1alpha1BrandingThemeHeaderTextAlignment.Center, HeaderTextAlignment.Center)] - [DataRow(V1alpha1BrandingThemeHeaderTextAlignment.Left, HeaderTextAlignment.Left)] - [DataRow(V1alpha1BrandingThemeHeaderTextAlignment.Right, HeaderTextAlignment.Right)] - public void ToApi_HeaderTextAlignment_MapsCorrectly(V1alpha1BrandingThemeHeaderTextAlignment input, HeaderTextAlignment expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.ToApi(input)); - } + public void ToApi_HeaderTextAlignment_Center() => Assert.AreEqual(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Center, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeHeaderTextAlignment.Center).Value); + + [TestMethod] + public void ToApi_HeaderTextAlignment_Left() => Assert.AreEqual(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Left, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeHeaderTextAlignment.Left).Value); + + [TestMethod] + public void ToApi_HeaderTextAlignment_Right() => Assert.AreEqual(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Right, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeHeaderTextAlignment.Right).Value); // ──────────────────────── ToApi PageLayout ──────────────────────────────── [TestMethod] - [DataRow(V1alpha1BrandingThemePageLayout.Right, PageLayout.Right)] - [DataRow(V1alpha1BrandingThemePageLayout.Center, PageLayout.Center)] - [DataRow(V1alpha1BrandingThemePageLayout.Left, PageLayout.Left)] - public void ToApi_PageLayout_MapsCorrectly(V1alpha1BrandingThemePageLayout input, PageLayout expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.ToApi(input)); - } + public void ToApi_PageLayout_Center() => Assert.AreEqual(BrandingThemePageBackgroundPageLayoutEnum.Values.Center, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemePageLayout.Center).Value); + + [TestMethod] + public void ToApi_PageLayout_Left() => Assert.AreEqual(BrandingThemePageBackgroundPageLayoutEnum.Values.Left, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemePageLayout.Left).Value); + + [TestMethod] + public void ToApi_PageLayout_Right() => Assert.AreEqual(BrandingThemePageBackgroundPageLayoutEnum.Values.Right, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemePageLayout.Right).Value); // ──────────────────────── ToApi ButtonsStyle ────────────────────────────── [TestMethod] - [DataRow(V1alpha1BrandingThemeButtonsStyle.Pill, ButtonsStyle.Pill)] - [DataRow(V1alpha1BrandingThemeButtonsStyle.Rounded, ButtonsStyle.Rounded)] - [DataRow(V1alpha1BrandingThemeButtonsStyle.Sharp, ButtonsStyle.Sharp)] - public void ToApi_ButtonsStyle_MapsCorrectly(V1alpha1BrandingThemeButtonsStyle input, ButtonsStyle expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.ToApi(input)); - } + public void ToApiButtonsStyle_Pill() => Assert.AreEqual(BrandingThemeBordersButtonsStyleEnum.Values.Pill, V1alpha1BrandingThemeController.ToApiButtonsStyle(V1alpha1BrandingThemeButtonsStyle.Pill).Value); + + [TestMethod] + public void ToApiButtonsStyle_Rounded() => Assert.AreEqual(BrandingThemeBordersButtonsStyleEnum.Values.Rounded, V1alpha1BrandingThemeController.ToApiButtonsStyle(V1alpha1BrandingThemeButtonsStyle.Rounded).Value); + + [TestMethod] + public void ToApiButtonsStyle_Sharp() => Assert.AreEqual(BrandingThemeBordersButtonsStyleEnum.Values.Sharp, V1alpha1BrandingThemeController.ToApiButtonsStyle(V1alpha1BrandingThemeButtonsStyle.Sharp).Value); // ──────────────────────── FromApi CaptchaWidgetTheme ───────────────────── [TestMethod] - [DataRow(CaptchaWidgetTheme.Light, V1alpha1BrandingThemeCaptchaWidgetTheme.Light)] - [DataRow(CaptchaWidgetTheme.Dark, V1alpha1BrandingThemeCaptchaWidgetTheme.Dark)] - [DataRow(CaptchaWidgetTheme.Auto, V1alpha1BrandingThemeCaptchaWidgetTheme.Auto)] - public void FromApi_CaptchaWidgetTheme_MapsCorrectly(CaptchaWidgetTheme input, V1alpha1BrandingThemeCaptchaWidgetTheme expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.FromApi(input)); - } + public void FromApi_CaptchaWidgetTheme_Light() => Assert.AreEqual(V1alpha1BrandingThemeCaptchaWidgetTheme.Light, V1alpha1BrandingThemeController.FromApi(new BrandingThemeColorsCaptchaWidgetThemeEnum(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Light))); + + [TestMethod] + public void FromApi_CaptchaWidgetTheme_Dark() => Assert.AreEqual(V1alpha1BrandingThemeCaptchaWidgetTheme.Dark, V1alpha1BrandingThemeController.FromApi(new BrandingThemeColorsCaptchaWidgetThemeEnum(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Dark))); + + [TestMethod] + public void FromApi_CaptchaWidgetTheme_Auto() => Assert.AreEqual(V1alpha1BrandingThemeCaptchaWidgetTheme.Auto, V1alpha1BrandingThemeController.FromApi(new BrandingThemeColorsCaptchaWidgetThemeEnum(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Auto))); // ──────────────────────── FromApi SocialButtonsLayout ──────────────────── [TestMethod] - [DataRow(SocialButtonsLayout.Top, V1alpha1BrandingThemeSocialButtonsLayout.Top)] - [DataRow(SocialButtonsLayout.Bottom, V1alpha1BrandingThemeSocialButtonsLayout.Bottom)] - public void FromApi_SocialButtonsLayout_MapsCorrectly(SocialButtonsLayout input, V1alpha1BrandingThemeSocialButtonsLayout expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.FromApi(input)); - } + public void FromApi_SocialButtonsLayout_Top() => Assert.AreEqual(V1alpha1BrandingThemeSocialButtonsLayout.Top, V1alpha1BrandingThemeController.FromApi(new BrandingThemeWidgetSocialButtonsLayoutEnum(BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Top))); + + [TestMethod] + public void FromApi_SocialButtonsLayout_Bottom() => Assert.AreEqual(V1alpha1BrandingThemeSocialButtonsLayout.Bottom, V1alpha1BrandingThemeController.FromApi(new BrandingThemeWidgetSocialButtonsLayoutEnum(BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Bottom))); // ──────────────────────── FromApi LogoPosition ─────────────────────────── [TestMethod] - [DataRow(LogoPosition.Center, V1alpha1BrandingThemeLogoPosition.Center)] - [DataRow(LogoPosition.Left, V1alpha1BrandingThemeLogoPosition.Left)] - [DataRow(LogoPosition.Right, V1alpha1BrandingThemeLogoPosition.Right)] - [DataRow(LogoPosition.None, V1alpha1BrandingThemeLogoPosition.None)] - public void FromApi_LogoPosition_MapsCorrectly(LogoPosition input, V1alpha1BrandingThemeLogoPosition expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.FromApi(input)); - } + public void FromApi_LogoPosition_Center() => Assert.AreEqual(V1alpha1BrandingThemeLogoPosition.Center, V1alpha1BrandingThemeController.FromApi(new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.Center))); + + [TestMethod] + public void FromApi_LogoPosition_Left() => Assert.AreEqual(V1alpha1BrandingThemeLogoPosition.Left, V1alpha1BrandingThemeController.FromApi(new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.Left))); + + [TestMethod] + public void FromApi_LogoPosition_Right() => Assert.AreEqual(V1alpha1BrandingThemeLogoPosition.Right, V1alpha1BrandingThemeController.FromApi(new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.Right))); + + [TestMethod] + public void FromApi_LogoPosition_None() => Assert.AreEqual(V1alpha1BrandingThemeLogoPosition.None, V1alpha1BrandingThemeController.FromApi(new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.None))); // ──────────────────────── FromApi HeaderTextAlignment ──────────────────── [TestMethod] - [DataRow(HeaderTextAlignment.Center, V1alpha1BrandingThemeHeaderTextAlignment.Center)] - [DataRow(HeaderTextAlignment.Left, V1alpha1BrandingThemeHeaderTextAlignment.Left)] - [DataRow(HeaderTextAlignment.Right, V1alpha1BrandingThemeHeaderTextAlignment.Right)] - public void FromApi_HeaderTextAlignment_MapsCorrectly(HeaderTextAlignment input, V1alpha1BrandingThemeHeaderTextAlignment expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.FromApi(input)); - } + public void FromApi_HeaderTextAlignment_Center() => Assert.AreEqual(V1alpha1BrandingThemeHeaderTextAlignment.Center, V1alpha1BrandingThemeController.FromApi(new BrandingThemeWidgetHeaderTextAlignmentEnum(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Center))); + + [TestMethod] + public void FromApi_HeaderTextAlignment_Left() => Assert.AreEqual(V1alpha1BrandingThemeHeaderTextAlignment.Left, V1alpha1BrandingThemeController.FromApi(new BrandingThemeWidgetHeaderTextAlignmentEnum(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Left))); + + [TestMethod] + public void FromApi_HeaderTextAlignment_Right() => Assert.AreEqual(V1alpha1BrandingThemeHeaderTextAlignment.Right, V1alpha1BrandingThemeController.FromApi(new BrandingThemeWidgetHeaderTextAlignmentEnum(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Right))); // ──────────────────────── FromApi PageLayout ───────────────────────────── [TestMethod] - [DataRow(PageLayout.Center, V1alpha1BrandingThemePageLayout.Center)] - [DataRow(PageLayout.Left, V1alpha1BrandingThemePageLayout.Left)] - [DataRow(PageLayout.Right, V1alpha1BrandingThemePageLayout.Right)] - public void FromApi_PageLayout_MapsCorrectly(PageLayout input, V1alpha1BrandingThemePageLayout expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.FromApi(input)); - } + public void FromApi_PageLayout_Center() => Assert.AreEqual(V1alpha1BrandingThemePageLayout.Center, V1alpha1BrandingThemeController.FromApi(new BrandingThemePageBackgroundPageLayoutEnum(BrandingThemePageBackgroundPageLayoutEnum.Values.Center))); + + [TestMethod] + public void FromApi_PageLayout_Left() => Assert.AreEqual(V1alpha1BrandingThemePageLayout.Left, V1alpha1BrandingThemeController.FromApi(new BrandingThemePageBackgroundPageLayoutEnum(BrandingThemePageBackgroundPageLayoutEnum.Values.Left))); + + [TestMethod] + public void FromApi_PageLayout_Right() => Assert.AreEqual(V1alpha1BrandingThemePageLayout.Right, V1alpha1BrandingThemeController.FromApi(new BrandingThemePageBackgroundPageLayoutEnum(BrandingThemePageBackgroundPageLayoutEnum.Values.Right))); // ──────────────────────── FromApi LinksStyle ───────────────────────────── [TestMethod] - [DataRow(LinksStyle.Normal, V1alpha1BrandingThemeLinksStyle.Normal)] - [DataRow(LinksStyle.Underlined, V1alpha1BrandingThemeLinksStyle.Underlined)] - public void FromApi_LinksStyle_MapsCorrectly(LinksStyle input, V1alpha1BrandingThemeLinksStyle expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.FromApi(input)); - } + public void FromApi_LinksStyle_Normal() => Assert.AreEqual(V1alpha1BrandingThemeLinksStyle.Normal, V1alpha1BrandingThemeController.FromApi(new BrandingThemeFontLinksStyleEnum(BrandingThemeFontLinksStyleEnum.Values.Normal))); + + [TestMethod] + public void FromApi_LinksStyle_Underlined() => Assert.AreEqual(V1alpha1BrandingThemeLinksStyle.Underlined, V1alpha1BrandingThemeController.FromApi(new BrandingThemeFontLinksStyleEnum(BrandingThemeFontLinksStyleEnum.Values.Underlined))); // ──────────────────────── FromApi ButtonsStyle ─────────────────────────── [TestMethod] - [DataRow(ButtonsStyle.Pill, V1alpha1BrandingThemeButtonsStyle.Pill)] - [DataRow(ButtonsStyle.Rounded, V1alpha1BrandingThemeButtonsStyle.Rounded)] - [DataRow(ButtonsStyle.Sharp, V1alpha1BrandingThemeButtonsStyle.Sharp)] - public void FromApi_ButtonsStyle_MapsCorrectly(ButtonsStyle input, V1alpha1BrandingThemeButtonsStyle expected) - { - Assert.AreEqual(expected, V1alpha1BrandingThemeController.FromApi(input)); - } + public void FromApi_ButtonsStyle_Pill() => Assert.AreEqual(V1alpha1BrandingThemeButtonsStyle.Pill, V1alpha1BrandingThemeController.FromApi(new BrandingThemeBordersButtonsStyleEnum(BrandingThemeBordersButtonsStyleEnum.Values.Pill))); + + [TestMethod] + public void FromApi_ButtonsStyle_Rounded() => Assert.AreEqual(V1alpha1BrandingThemeButtonsStyle.Rounded, V1alpha1BrandingThemeController.FromApi(new BrandingThemeBordersButtonsStyleEnum(BrandingThemeBordersButtonsStyleEnum.Values.Rounded))); + + [TestMethod] + public void FromApi_ButtonsStyle_Sharp() => Assert.AreEqual(V1alpha1BrandingThemeButtonsStyle.Sharp, V1alpha1BrandingThemeController.FromApi(new BrandingThemeBordersButtonsStyleEnum(BrandingThemeBordersButtonsStyleEnum.Values.Sharp))); // ──────────────────────── Roundtrip tests ───────────────────────────────── [TestMethod] - [DataRow(CaptchaWidgetTheme.Light)] - [DataRow(CaptchaWidgetTheme.Dark)] - [DataRow(CaptchaWidgetTheme.Auto)] - public void CaptchaWidgetTheme_Roundtrip(CaptchaWidgetTheme input) - { - var op = V1alpha1BrandingThemeController.FromApi(input)!.Value; - Assert.AreEqual(input, V1alpha1BrandingThemeController.ToApi(op)); - } - - [TestMethod] - [DataRow(SocialButtonsLayout.Top)] - [DataRow(SocialButtonsLayout.Bottom)] - public void SocialButtonsLayout_Roundtrip(SocialButtonsLayout input) - { - var op = V1alpha1BrandingThemeController.FromApi(input)!.Value; - Assert.AreEqual(input, V1alpha1BrandingThemeController.ToApi(op)); - } - - [TestMethod] - [DataRow(LogoPosition.Center)] - [DataRow(LogoPosition.Left)] - [DataRow(LogoPosition.Right)] - [DataRow(LogoPosition.None)] - public void LogoPosition_Roundtrip(LogoPosition input) - { - var op = V1alpha1BrandingThemeController.FromApi(input)!.Value; - Assert.AreEqual(input, V1alpha1BrandingThemeController.ToApi(op)); - } - - [TestMethod] - [DataRow(HeaderTextAlignment.Center)] - [DataRow(HeaderTextAlignment.Left)] - [DataRow(HeaderTextAlignment.Right)] - public void HeaderTextAlignment_Roundtrip(HeaderTextAlignment input) - { - var op = V1alpha1BrandingThemeController.FromApi(input)!.Value; - Assert.AreEqual(input, V1alpha1BrandingThemeController.ToApi(op)); - } - - [TestMethod] - [DataRow(PageLayout.Center)] - [DataRow(PageLayout.Left)] - [DataRow(PageLayout.Right)] - public void PageLayout_Roundtrip(PageLayout input) - { - var op = V1alpha1BrandingThemeController.FromApi(input)!.Value; - Assert.AreEqual(input, V1alpha1BrandingThemeController.ToApi(op)); - } - - [TestMethod] - [DataRow(ButtonsStyle.Pill)] - [DataRow(ButtonsStyle.Rounded)] - [DataRow(ButtonsStyle.Sharp)] - public void ButtonsStyle_Roundtrip(ButtonsStyle input) - { - var op = V1alpha1BrandingThemeController.FromApi(input); - Assert.AreEqual(input, V1alpha1BrandingThemeController.ToApi(op)); - } + public void CaptchaWidgetTheme_Roundtrip_Light() { var input = new BrandingThemeColorsCaptchaWidgetThemeEnum(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Light); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void CaptchaWidgetTheme_Roundtrip_Dark() { var input = new BrandingThemeColorsCaptchaWidgetThemeEnum(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Dark); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void CaptchaWidgetTheme_Roundtrip_Auto() { var input = new BrandingThemeColorsCaptchaWidgetThemeEnum(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Auto); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void SocialButtonsLayout_Roundtrip_Top() { var input = new BrandingThemeWidgetSocialButtonsLayoutEnum(BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Top); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void SocialButtonsLayout_Roundtrip_Bottom() { var input = new BrandingThemeWidgetSocialButtonsLayoutEnum(BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Bottom); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void LogoPosition_Roundtrip_Center() { var input = new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.Center); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void LogoPosition_Roundtrip_Left() { var input = new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.Left); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void LogoPosition_Roundtrip_Right() { var input = new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.Right); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void LogoPosition_Roundtrip_None() { var input = new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.None); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void HeaderTextAlignment_Roundtrip_Center() { var input = new BrandingThemeWidgetHeaderTextAlignmentEnum(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Center); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void HeaderTextAlignment_Roundtrip_Left() { var input = new BrandingThemeWidgetHeaderTextAlignmentEnum(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Left); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void HeaderTextAlignment_Roundtrip_Right() { var input = new BrandingThemeWidgetHeaderTextAlignmentEnum(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Right); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void PageLayout_Roundtrip_Center() { var input = new BrandingThemePageBackgroundPageLayoutEnum(BrandingThemePageBackgroundPageLayoutEnum.Values.Center); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void PageLayout_Roundtrip_Left() { var input = new BrandingThemePageBackgroundPageLayoutEnum(BrandingThemePageBackgroundPageLayoutEnum.Values.Left); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void PageLayout_Roundtrip_Right() { var input = new BrandingThemePageBackgroundPageLayoutEnum(BrandingThemePageBackgroundPageLayoutEnum.Values.Right); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApi(V1alpha1BrandingThemeController.FromApi(input)!.Value).Value); } + + [TestMethod] + public void ButtonsStyle_Roundtrip_Pill() { var input = new BrandingThemeBordersButtonsStyleEnum(BrandingThemeBordersButtonsStyleEnum.Values.Pill); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApiButtonsStyle(V1alpha1BrandingThemeController.FromApi(input)).Value); } + + [TestMethod] + public void ButtonsStyle_Roundtrip_Rounded() { var input = new BrandingThemeBordersButtonsStyleEnum(BrandingThemeBordersButtonsStyleEnum.Values.Rounded); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApiButtonsStyle(V1alpha1BrandingThemeController.FromApi(input)).Value); } + + [TestMethod] + public void ButtonsStyle_Roundtrip_Sharp() { var input = new BrandingThemeBordersButtonsStyleEnum(BrandingThemeBordersButtonsStyleEnum.Values.Sharp); Assert.AreEqual(input.Value, V1alpha1BrandingThemeController.ToApiButtonsStyle(V1alpha1BrandingThemeController.FromApi(input)).Value); } } diff --git a/src/Alethic.Auth0.Operator.Tests/V2alpha1ClientControllerMappingTests.cs b/src/Alethic.Auth0.Operator.Tests/V2alpha1ClientControllerMappingTests.cs new file mode 100644 index 0000000..3fb4b8c --- /dev/null +++ b/src/Alethic.Auth0.Operator.Tests/V2alpha1ClientControllerMappingTests.cs @@ -0,0 +1,792 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +using Alethic.Auth0.Operator.Controllers; +using Alethic.Auth0.Operator.Core.Models.Client.V1; +using Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; +using Alethic.Auth0.Operator.Models; + +using Auth0.ManagementApi; +using Auth0.ManagementApi.Core; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Alethic.Auth0.Operator.Tests +{ + + using V2alpha1ClientEntity = Alethic.Auth0.Operator.Models.V2alpha1Client; + + [TestClass] + [System.Runtime.Versioning.RequiresPreviewFeatures] + public class V2alpha1ClientControllerMappingTests + { + + [TestMethod] + public void FromApi_Client_Null_ReturnsNull() + { + Assert.IsNull(V2alpha1ClientController.FromApi((GetClientResponseContent?)null)); + } + + [TestMethod] + public void FromApi_Client_MapsScalarProperties() + { + var source = new GetClientResponseContent + { + Name = "My App", + Description = "Test app", + LogoUri = "https://example.com/logo.png", + OidcConformant = true, + Sso = false, + CrossOriginAuthentication = true, + IsFirstParty = true, + AppType = new ClientAppTypeEnum(ClientAppTypeEnum.Values.RegularWeb), + TokenEndpointAuthMethod = new ClientTokenEndpointAuthMethodEnum(ClientTokenEndpointAuthMethodEnum.Values.ClientSecretPost), + ComplianceLevel = Optional.Of(new ClientComplianceLevelEnum(ClientComplianceLevelEnum.Values.Fapi1AdvPkjPar)), + OrganizationUsage = new ClientOrganizationUsageEnum(ClientOrganizationUsageEnum.Values.Require), + OrganizationRequireBehavior = new ClientOrganizationRequireBehaviorEnum(ClientOrganizationRequireBehaviorEnum.Values.PreLoginPrompt), + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.AreEqual("My App", result.Name); + Assert.AreEqual("Test app", result.Description); + Assert.AreEqual("https://example.com/logo.png", result.LogoUri); + Assert.AreEqual(true, result.OidcConformant); + Assert.AreEqual(false, result.Sso); + Assert.AreEqual(true, result.CrossOriginAuthentication); + Assert.AreEqual(true, result.IsFirstParty); + Assert.AreEqual(V2alpha1ClientAppTypeEnum.RegularWeb, result.ApplicationType); + Assert.AreEqual(V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretPost, result.TokenEndpointAuthMethod); + Assert.AreEqual(V2alpha1ClientComplianceLevelEnum.Fapi1AdvPkjPar, result.ComplianceLevel); + Assert.AreEqual(V2alpha1ClientOrganizationUsageEnum.Require, result.OrganizationUsage); + Assert.AreEqual(V2alpha1ClientOrganizationRequireBehaviorEnum.PreLoginPrompt, result.OrganizationRequireBehavior); + } + + [TestMethod] + public void FromApi_Client_MapsArrayProperties() + { + var source = new GetClientResponseContent + { + AllowedClients = ["client-1", "client-2"], + AllowedLogoutUrls = ["https://example.com/logout"], + AllowedOrigins = ["https://origin.example.com"], + WebOrigins = ["https://web.example.com"], + Callbacks = ["https://example.com/callback"], + ClientAliases = ["alias-1", "alias-2"], + GrantTypes = ["authorization_code", "refresh_token"], + ClientMetadata = new Dictionary + { + ["environment"] = "test", + ["enabled"] = true, + }, + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + CollectionAssert.AreEqual(new[] { "client-1", "client-2" }, result.AllowedClients); + CollectionAssert.AreEqual(new[] { "https://example.com/logout" }, result.AllowedLogoutUrls); + CollectionAssert.AreEqual(new[] { "https://origin.example.com" }, result.AllowedOrigins); + CollectionAssert.AreEqual(new[] { "https://web.example.com" }, result.WebOrigins); + CollectionAssert.AreEqual(new[] { "https://example.com/callback" }, result.Callbacks); + CollectionAssert.AreEqual(new[] { "alias-1", "alias-2" }, result.ClientAliases); + CollectionAssert.AreEqual(new[] { "authorization_code", "refresh_token" }, result.GrantTypes); + Assert.IsNotNull(result.ClientMetaData); + Assert.AreEqual("test", result.ClientMetaData["environment"]); + Assert.AreEqual(true, result.ClientMetaData["enabled"]); + } + + [TestMethod] + public void FromApi_SigningKey_MapsProperties() + { + var source = new ClientSigningKey + { + Cert = "cert", + Pkcs7 = "pkcs7", + Subject = "subject", + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.AreEqual("cert", result.Cert); + Assert.AreEqual("pkcs7", result.Pkcs7); + Assert.AreEqual("subject", result.Subject); + } + + [TestMethod] + public void FromApi_EncryptionKey_MapsProperties() + { + var source = new ClientEncryptionKey + { + Cert = "cert", + Pub = "pub", + Subject = "subject", + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.AreEqual("cert", result.Cert); + Assert.AreEqual("pub", result.Pub); + Assert.AreEqual("subject", result.Subject); + } + + [TestMethod] + public void FromApi_JwtConfiguration_MapsProperties() + { + var source = new ClientJwtConfiguration + { + SecretEncoded = true, + LifetimeInSeconds = 3600, + Alg = new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Rs256), + Scopes = new Dictionary + { + ["read:data"] = "allow", + }, + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.AreEqual(true, result.SecretEncoded); + Assert.AreEqual(3600, result.LifetimeInSeconds); + Assert.AreEqual(V2alpha1ClientSigningAlgorithmEnum.Rs256, result.Alg); + Assert.IsNotNull(result.Scopes); + Assert.AreEqual("allow", result.Scopes["read:data"]); + } + + [TestMethod] + public void FromApi_RefreshToken_MapsProperties() + { + var source = new ClientRefreshTokenConfiguration + { + RotationType = new RefreshTokenRotationTypeEnum(RefreshTokenRotationTypeEnum.Values.Rotating), + ExpirationType = new RefreshTokenExpirationTypeEnum(RefreshTokenExpirationTypeEnum.Values.Expiring), + Leeway = 10, + TokenLifetime = 7200, + InfiniteTokenLifetime = false, + IdleTokenLifetime = 1800, + InfiniteIdleTokenLifetime = false, + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.AreEqual(V2alpha1ClientRefreshTokenRotationTypeEnum.Rotating, result.RotationType); + Assert.AreEqual(V2alpha1ClientRefreshTokenExpirationTypeEnum.Expiring, result.ExpirationType); + Assert.AreEqual(10, result.Leeway); + Assert.AreEqual(7200, result.TokenLifetime); + Assert.AreEqual(false, result.InfiniteTokenLifetime); + Assert.AreEqual(1800, result.IdleTokenLifetime); + Assert.AreEqual(false, result.InfiniteIdleTokenLifetime); + } + + [TestMethod] + public void FromApi_Client_MapsOidcLogoutSessionMetadata() + { + var source = new ClientOidcBackchannelLogoutSettings + { + BackchannelLogoutUrls = ["https://example.com/logout"], + BackchannelLogoutInitiators = new ClientOidcBackchannelLogoutInitiators + { + Mode = new ClientOidcBackchannelLogoutInitiatorsModeEnum(ClientOidcBackchannelLogoutInitiatorsModeEnum.Values.Custom), + SelectedInitiators = [new ClientOidcBackchannelLogoutInitiatorsEnum(ClientOidcBackchannelLogoutInitiatorsEnum.Values.RpLogout)], + }, + BackchannelLogoutSessionMetadata = Optional.Of( + new ClientOidcBackchannelLogoutSessionMetadata { Include = true }), + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + CollectionAssert.AreEqual(new[] { "https://example.com/logout" }, result.BackchannelLogoutUrls); + Assert.IsNotNull(result.BackchannelLogoutInitiators); + Assert.AreEqual(V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.Custom, result.BackchannelLogoutInitiators.Mode); + CollectionAssert.AreEqual(new[] { V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.RpLogout }, result.BackchannelLogoutInitiators.SelectedInitiators); + Assert.IsNotNull(result.BackchannelLogoutSessionMetadata); + Assert.AreEqual(true, result.BackchannelLogoutSessionMetadata.Include); + } + + [TestMethod] + public void FromApi_BackchannelLogoutInitiators_MapsProperties() + { + var source = new ClientOidcBackchannelLogoutInitiators + { + Mode = new ClientOidcBackchannelLogoutInitiatorsModeEnum(ClientOidcBackchannelLogoutInitiatorsModeEnum.Values.All), + SelectedInitiators = + [ + new ClientOidcBackchannelLogoutInitiatorsEnum(ClientOidcBackchannelLogoutInitiatorsEnum.Values.RpLogout), + new ClientOidcBackchannelLogoutInitiatorsEnum(ClientOidcBackchannelLogoutInitiatorsEnum.Values.SessionExpired), + ], + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.AreEqual(V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.All, result.Mode); + CollectionAssert.AreEqual( + new[] + { + V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.RpLogout, + V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.SessionExpired, + }, + result.SelectedInitiators); + } + + [TestMethod] + public void FromApi_DefaultOrganization_MapsProperties() + { + var source = new ClientDefaultOrganization + { + OrganizationId = "org_123", + Flows = [new ClientDefaultOrganizationFlowsEnum(ClientDefaultOrganizationFlowsEnum.Values.ClientCredentials)], + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.AreEqual("org_123", result.OrganizationId); + CollectionAssert.AreEqual(new[] { V2alpha1ClientDefaultOrganizationFlowsEnum.ClientCredentials }, result.Flows); + } + + [TestMethod] + public void FromApi_SharePointAddon_MapsExternalUrlAsArray() + { + var source = new ClientAddonSharePoint + { + Url = "https://sharepoint.example.com", + ExternalUrl = ClientAddonSharePointExternalUrl.FromListOfString(["https://external.example.com", "https://external2.example.com"]), + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.AreEqual("https://sharepoint.example.com", result.Url); + CollectionAssert.AreEqual(new[] { "https://external.example.com", "https://external2.example.com" }, result.ExternalUrl); + } + + [TestMethod] + public void FromApi_SharePointAddon_StringExternalUrl_MapsToSingleItemArray() + { + var source = new ClientAddonSharePoint + { + ExternalUrl = ClientAddonSharePointExternalUrl.FromString("https://external.example.com"), + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + CollectionAssert.AreEqual(new[] { "https://external.example.com" }, result.ExternalUrl); + } + + [TestMethod] + public void FromApi_Mobile_WithIosAndAndroid_MapsProperties() + { + var source = new ClientMobile + { + Ios = new ClientMobileiOs + { + AppBundleIdentifier = "com.example.ios", + TeamId = "TEAM123", + }, + Android = new ClientMobileAndroid + { + AppPackageName = "com.example.android", + }, + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.IsNotNull(result.Ios); + Assert.AreEqual("com.example.ios", result.Ios.AppBundleIdentifier); + Assert.AreEqual("TEAM123", result.Ios.TeamId); + Assert.IsNotNull(result.Android); + Assert.AreEqual("com.example.android", result.Android.AppPackageName); + } + + [TestMethod] + public void FromApi_Mobile_WithEmptyIos_ReturnsNullIos() + { + var source = new ClientMobile + { + Ios = new ClientMobileiOs(), + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.IsNull(result.Ios); + } + + [TestMethod] + public void FromApi_Mobile_WithEmptyAndroid_ReturnsNullAndroid() + { + var source = new ClientMobile + { + Android = new ClientMobileAndroid(), + }; + + var result = V2alpha1ClientController.FromApi(source); + + Assert.IsNotNull(result); + Assert.IsNull(result.Android); + } + + [TestMethod] + public void ApplyToApi_Create_MapsOidcLogoutSessionMetadata() + { + var conf = new V2alpha1ClientConf + { + Name = "my-app", + ApplicationType = V2alpha1ClientAppTypeEnum.RegularWeb, + OidcLogout = new V2alpha1ClientOidcBackchannelLogoutSettings + { + BackchannelLogoutUrls = ["https://example.com/logout"], + BackchannelLogoutInitiators = new V2alpha1ClientOidcBackchannelLogoutInitiators + { + Mode = V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.Custom, + SelectedInitiators = [V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.RpLogout], + }, + BackchannelLogoutSessionMetadata = new V2alpha1ClientOidcBackchannelLogoutSessionMetadata + { + Include = true, + }, + }, + }; + + var request = new CreateClientRequestContent { Name = conf.Name! }; + V2alpha1ClientController.ApplyToApi(conf, request); + + Assert.IsNotNull(request.OidcLogout); + CollectionAssert.AreEqual(new[] { "https://example.com/logout" }, request.OidcLogout.BackchannelLogoutUrls?.ToArray()); + Assert.IsNotNull(request.OidcLogout.BackchannelLogoutInitiators); + Assert.AreEqual(ClientOidcBackchannelLogoutInitiatorsModeEnum.Values.Custom, request.OidcLogout.BackchannelLogoutInitiators.Mode?.Value); + CollectionAssert.AreEqual( + new[] { ClientOidcBackchannelLogoutInitiatorsEnum.Values.RpLogout }, + request.OidcLogout.BackchannelLogoutInitiators.SelectedInitiators?.Select(static i => i.Value).ToArray()); + Assert.IsTrue(request.OidcLogout.BackchannelLogoutSessionMetadata.IsDefined); + Assert.AreEqual(true, request.OidcLogout.BackchannelLogoutSessionMetadata.Value?.Include); + } + + [TestMethod] + public void ApplyToApi_Create_MapsDefaultOrganization() + { + var conf = new V2alpha1ClientConf + { + Name = "my-app", + ApplicationType = V2alpha1ClientAppTypeEnum.RegularWeb, + DefaultOrganization = new V2alpha1ClientDefaultOrganization + { + OrganizationId = "org_123", + Flows = [V2alpha1ClientDefaultOrganizationFlowsEnum.ClientCredentials], + }, + }; + + var request = new CreateClientRequestContent { Name = conf.Name! }; + V2alpha1ClientController.ApplyToApi(conf, request); + + Assert.IsTrue(request.DefaultOrganization.IsDefined); + Assert.AreEqual("org_123", request.DefaultOrganization.Value?.OrganizationId); + CollectionAssert.AreEqual( + new[] { ClientDefaultOrganizationFlowsEnum.Values.ClientCredentials }, + request.DefaultOrganization.Value?.Flows?.Select(static i => i.Value).ToArray()); + } + + [TestMethod] + public void ApplyToApi_Create_MapsSharePointAddonExternalUrlAsList() + { + var conf = new V2alpha1ClientConf + { + Name = "my-app", + ApplicationType = V2alpha1ClientAppTypeEnum.RegularWeb, + AddOns = new V2alpha1ClientAddons + { + Sharepoint = new V2alpha1ClientAddonSharePoint + { + Url = "https://sharepoint.example.com", + ExternalUrl = ["https://external.example.com", "https://external2.example.com"], + }, + }, + }; + + var request = new CreateClientRequestContent { Name = conf.Name! }; + V2alpha1ClientController.ApplyToApi(conf, request); + + Assert.IsNotNull(request.Addons?.Sharepoint); + Assert.AreEqual("https://sharepoint.example.com", request.Addons.Sharepoint.Url); + Assert.IsNotNull(request.Addons.Sharepoint.ExternalUrl); + Assert.IsTrue(request.Addons.Sharepoint.ExternalUrl.TryGetListOfString(out var values)); + CollectionAssert.AreEqual(new[] { "https://external.example.com", "https://external2.example.com" }, values?.ToArray()); + } + + [TestMethod] + public void FromApi_EnumNulls_ReturnNull() + { + Assert.IsNull(V2alpha1ClientController.FromApi((ClientAppTypeEnum?)null)); + Assert.IsNull(V2alpha1ClientController.FromApi((ClientTokenEndpointAuthMethodEnum?)null)); + Assert.IsNull(V2alpha1ClientController.FromApi((RefreshTokenRotationTypeEnum?)null)); + Assert.IsNull(V2alpha1ClientController.FromApi((RefreshTokenExpirationTypeEnum?)null)); + Assert.IsNull(V2alpha1ClientController.FromApi((ClientOrganizationUsageEnum?)null)); + Assert.IsNull(V2alpha1ClientController.FromApi((ClientOrganizationRequireBehaviorEnum?)null)); + Assert.IsNull(V2alpha1ClientController.FromApi((ClientComplianceLevelEnum?)null)); + Assert.IsNull(V2alpha1ClientController.FromApi((ClientOidcBackchannelLogoutInitiatorsModeEnum?)null)); + } + + [TestMethod] + public void ClientApplicationTypes_Roundtrip_AllSupportedValues() + { + var cases = new (string Api, V2alpha1ClientAppTypeEnum Model)[] + { + (ClientAppTypeEnum.Values.Native, V2alpha1ClientAppTypeEnum.Native), + (ClientAppTypeEnum.Values.NonInteractive, V2alpha1ClientAppTypeEnum.NonInteractive), + (ClientAppTypeEnum.Values.Spa, V2alpha1ClientAppTypeEnum.Spa), + (ClientAppTypeEnum.Values.RegularWeb, V2alpha1ClientAppTypeEnum.RegularWeb), + (ClientAppTypeEnum.Values.Box, V2alpha1ClientAppTypeEnum.Box), + (ClientAppTypeEnum.Values.Cloudbees, V2alpha1ClientAppTypeEnum.Cloudbees), + (ClientAppTypeEnum.Values.Concur, V2alpha1ClientAppTypeEnum.Concur), + (ClientAppTypeEnum.Values.Dropbox, V2alpha1ClientAppTypeEnum.Dropbox), + (ClientAppTypeEnum.Values.Echosign, V2alpha1ClientAppTypeEnum.Echosign), + (ClientAppTypeEnum.Values.Egnyte, V2alpha1ClientAppTypeEnum.Egnyte), + (ClientAppTypeEnum.Values.Mscrm, V2alpha1ClientAppTypeEnum.Mscrm), + (ClientAppTypeEnum.Values.Newrelic, V2alpha1ClientAppTypeEnum.Newrelic), + (ClientAppTypeEnum.Values.Office365, V2alpha1ClientAppTypeEnum.Office365), + (ClientAppTypeEnum.Values.Rms, V2alpha1ClientAppTypeEnum.Rms), + (ClientAppTypeEnum.Values.Salesforce, V2alpha1ClientAppTypeEnum.Salesforce), + (ClientAppTypeEnum.Values.Sentry, V2alpha1ClientAppTypeEnum.Sentry), + (ClientAppTypeEnum.Values.Sharepoint, V2alpha1ClientAppTypeEnum.Sharepoint), + (ClientAppTypeEnum.Values.Slack, V2alpha1ClientAppTypeEnum.Slack), + (ClientAppTypeEnum.Values.Springcm, V2alpha1ClientAppTypeEnum.Springcm), + (ClientAppTypeEnum.Values.Zendesk, V2alpha1ClientAppTypeEnum.Zendesk), + (ClientAppTypeEnum.Values.Zoom, V2alpha1ClientAppTypeEnum.Zoom), + (ClientAppTypeEnum.Values.ResourceServer, V2alpha1ClientAppTypeEnum.ResourceServer), + (ClientAppTypeEnum.Values.ExpressConfiguration, V2alpha1ClientAppTypeEnum.ExpressConfiguration), + (ClientAppTypeEnum.Values.SsoIntegration, V2alpha1ClientAppTypeEnum.SsoIntegration), + (ClientAppTypeEnum.Values.Oag, V2alpha1ClientAppTypeEnum.Oag), + }; + + foreach (var testCase in cases) + { + Assert.AreEqual(testCase.Model, V2alpha1ClientController.FromApi(new ClientAppTypeEnum(testCase.Api))); + Assert.AreEqual(testCase.Api, V2alpha1ClientController.ToApi(testCase.Model).Value); + } + } + + [TestMethod] + public void TokenEndpointAuthMethod_Roundtrip_AllSupportedValues() + { + var cases = new (string Api, V2alpha1ClientTokenEndpointAuthMethodEnum Model)[] + { + (ClientTokenEndpointAuthMethodEnum.Values.None, V2alpha1ClientTokenEndpointAuthMethodEnum.None), + (ClientTokenEndpointAuthMethodEnum.Values.ClientSecretPost, V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretPost), + (ClientTokenEndpointAuthMethodEnum.Values.ClientSecretBasic, V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretBasic), + }; + + foreach (var testCase in cases) + { + Assert.AreEqual(testCase.Model, V2alpha1ClientController.FromApi(new ClientTokenEndpointAuthMethodEnum(testCase.Api))); + Assert.AreEqual(testCase.Api, V2alpha1ClientController.ToApi(testCase.Model).Value); + } + } + + [TestMethod] + public void RefreshTokenRotationType_Roundtrip_AllSupportedValues() + { + var cases = new (string Api, V2alpha1ClientRefreshTokenRotationTypeEnum Model)[] + { + (RefreshTokenRotationTypeEnum.Values.Rotating, V2alpha1ClientRefreshTokenRotationTypeEnum.Rotating), + (RefreshTokenRotationTypeEnum.Values.NonRotating, V2alpha1ClientRefreshTokenRotationTypeEnum.NonRotating), + }; + + foreach (var testCase in cases) + { + Assert.AreEqual(testCase.Model, V2alpha1ClientController.FromApi(new RefreshTokenRotationTypeEnum(testCase.Api))); + Assert.AreEqual(testCase.Api, V2alpha1ClientController.ToApi(testCase.Model).Value); + } + } + + [TestMethod] + public void RefreshTokenExpirationType_Roundtrip_AllSupportedValues() + { + var cases = new (string Api, V2alpha1ClientRefreshTokenExpirationTypeEnum Model)[] + { + (RefreshTokenExpirationTypeEnum.Values.Expiring, V2alpha1ClientRefreshTokenExpirationTypeEnum.Expiring), + (RefreshTokenExpirationTypeEnum.Values.NonExpiring, V2alpha1ClientRefreshTokenExpirationTypeEnum.NonExpiring), + }; + + foreach (var testCase in cases) + { + Assert.AreEqual(testCase.Model, V2alpha1ClientController.FromApi(new RefreshTokenExpirationTypeEnum(testCase.Api))); + Assert.AreEqual(testCase.Api, V2alpha1ClientController.ToApi(testCase.Model).Value); + } + } + + [TestMethod] + public void OrganizationUsage_Roundtrip_AllSupportedValues() + { + var cases = new (string Api, V2alpha1ClientOrganizationUsageEnum Model)[] + { + (ClientOrganizationUsageEnum.Values.Deny, V2alpha1ClientOrganizationUsageEnum.Deny), + (ClientOrganizationUsageEnum.Values.Allow, V2alpha1ClientOrganizationUsageEnum.Allow), + (ClientOrganizationUsageEnum.Values.Require, V2alpha1ClientOrganizationUsageEnum.Require), + }; + + foreach (var testCase in cases) + { + Assert.AreEqual(testCase.Model, V2alpha1ClientController.FromApi(new ClientOrganizationUsageEnum(testCase.Api))); + Assert.AreEqual(testCase.Api, V2alpha1ClientController.ToApi(testCase.Model).Value); + } + } + + [TestMethod] + public void OrganizationRequireBehavior_Roundtrip_AllSupportedValues() + { + var cases = new (string Api, V2alpha1ClientOrganizationRequireBehaviorEnum Model)[] + { + (ClientOrganizationRequireBehaviorEnum.Values.NoPrompt, V2alpha1ClientOrganizationRequireBehaviorEnum.NoPrompt), + (ClientOrganizationRequireBehaviorEnum.Values.PreLoginPrompt, V2alpha1ClientOrganizationRequireBehaviorEnum.PreLoginPrompt), + (ClientOrganizationRequireBehaviorEnum.Values.PostLoginPrompt, V2alpha1ClientOrganizationRequireBehaviorEnum.PostLoginPrompt), + }; + + foreach (var testCase in cases) + { + Assert.AreEqual(testCase.Model, V2alpha1ClientController.FromApi(new ClientOrganizationRequireBehaviorEnum(testCase.Api))); + Assert.AreEqual(testCase.Api, V2alpha1ClientController.ToApi(testCase.Model).Value); + } + } + + [TestMethod] + public void ComplianceLevel_Roundtrip_AllSupportedValues() + { + var cases = new (string Api, V2alpha1ClientComplianceLevelEnum Model)[] + { + (ClientComplianceLevelEnum.Values.None, V2alpha1ClientComplianceLevelEnum.None), + (ClientComplianceLevelEnum.Values.Fapi1AdvPkjPar, V2alpha1ClientComplianceLevelEnum.Fapi1AdvPkjPar), + (ClientComplianceLevelEnum.Values.Fapi1AdvMtlsPar, V2alpha1ClientComplianceLevelEnum.Fapi1AdvMtlsPar), + (ClientComplianceLevelEnum.Values.Fapi2SpPkjMtls, V2alpha1ClientComplianceLevelEnum.Fapi2SpPkjMtls), + (ClientComplianceLevelEnum.Values.Fapi2SpMtlsMtls, V2alpha1ClientComplianceLevelEnum.Fapi2SpMtlsMtls), + }; + + foreach (var testCase in cases) + { + Assert.AreEqual(testCase.Model, V2alpha1ClientController.FromApi(new ClientComplianceLevelEnum(testCase.Api))); + Assert.AreEqual(testCase.Api, V2alpha1ClientController.ToApi(testCase.Model).Value); + } + } + + [TestMethod] + public void LogoutInitiators_Roundtrip_AllSupportedValues() + { + var cases = new string[] + { + ClientOidcBackchannelLogoutInitiatorsEnum.Values.RpLogout, + ClientOidcBackchannelLogoutInitiatorsEnum.Values.IdpLogout, + ClientOidcBackchannelLogoutInitiatorsEnum.Values.PasswordChanged, + ClientOidcBackchannelLogoutInitiatorsEnum.Values.SessionExpired, + }; + + foreach (var testCase in cases) + { + var result = V2alpha1ClientController.FromApi(new ClientOidcBackchannelLogoutInitiatorsEnum(testCase)); + Assert.AreEqual(testCase, V2alpha1ClientController.ToApi(result).Value); + } + } + + [TestMethod] + public void LogoutInitiatorModes_Roundtrip_AllSupportedValues() + { + var cases = new (string Api, V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum Model)[] + { + (ClientOidcBackchannelLogoutInitiatorsModeEnum.Values.All, V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.All), + (ClientOidcBackchannelLogoutInitiatorsModeEnum.Values.Custom, V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.Custom), + }; + + foreach (var testCase in cases) + { + Assert.AreEqual(testCase.Model, V2alpha1ClientController.FromApi(new ClientOidcBackchannelLogoutInitiatorsModeEnum(testCase.Api))); + Assert.AreEqual(testCase.Api, V2alpha1ClientController.ToApi(testCase.Model).Value); + } + } + + [TestMethod] + public void Converter_ConvertConf_MapsClientSpecificFields() + { + var source = new V1Client + { + Spec = + { + Find = new V1ClientFind { ClientId = "abc123", Name = "legacy-app" }, + Conf = new V1ClientConf + { + Name = "legacy-app", + ApplicationType = V1ClientApplicationType.RegularWeb, + TokenEndpointAuthMethod = V1ClientTokenEndpointAuthMethod.ClientSecretPost, + ComplianceLevel = V1ClientComplianceLevel.Fapi1AdvPkjPar, + OrganizationUsage = V1ClientOrganizationUsage.Require, + OrganizationRequireBehavior = V1ClientOrganizationRequireBehavior.PostLoginPrompt, + RefreshToken = new V1ClientRefreshToken + { + RotationType = V1ClientRefreshTokenRotationType.Rotating, + ExpirationType = V1ClientRefreshTokenExpirationType.Expiring, + Leeway = 10, + TokenLifetime = 7200, + InfiniteTokenLifetime = false, + IdleTokenLifetime = 1800, + InfiniteIdleTokenLifetime = false, + }, + DefaultOrganization = new V1ClientDefaultOrganization + { + OrganizationId = "org_123", + Flows = [V1ClientFlows.ClientCredentials], + }, + OidcLogout = new V1ClientOidcLogoutConfig + { + BackchannelLogoutUrls = ["https://example.com/logout"], + BackchannelLogoutInitiators = new V1ClientBackchannelLogoutInitiators + { + Mode = V1ClientLogoutInitiatorModes.Custom, + SelectedInitiators = [V1ClientLogoutInitiators.RpLogout], + }, + }, + }, + }, + Status = + { + Id = "cli_123", + }, + }; + + var result = InvokeConvert(source); + + Assert.AreEqual("abc123", result.Spec.Find?.ClientId); + Assert.AreEqual("legacy-app", result.Spec.Find?.Name); + Assert.AreEqual("cli_123", result.Status.Id); + Assert.AreEqual(V2alpha1ClientAppTypeEnum.RegularWeb, result.Spec.Conf?.ApplicationType); + Assert.AreEqual(V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretPost, result.Spec.Conf?.TokenEndpointAuthMethod); + Assert.AreEqual(V2alpha1ClientComplianceLevelEnum.Fapi1AdvPkjPar, result.Spec.Conf?.ComplianceLevel); + Assert.AreEqual(V2alpha1ClientOrganizationUsageEnum.Require, result.Spec.Conf?.OrganizationUsage); + Assert.AreEqual(V2alpha1ClientOrganizationRequireBehaviorEnum.PostLoginPrompt, result.Spec.Conf?.OrganizationRequireBehavior); + Assert.IsNotNull(result.Spec.Conf?.RefreshToken); + Assert.AreEqual(V2alpha1ClientRefreshTokenRotationTypeEnum.Rotating, result.Spec.Conf.RefreshToken.RotationType); + Assert.AreEqual(V2alpha1ClientRefreshTokenExpirationTypeEnum.Expiring, result.Spec.Conf.RefreshToken.ExpirationType); + Assert.AreEqual(10, result.Spec.Conf.RefreshToken.Leeway); + Assert.IsNotNull(result.Spec.Conf.DefaultOrganization); + Assert.AreEqual("org_123", result.Spec.Conf.DefaultOrganization.OrganizationId); + CollectionAssert.AreEqual(new[] { V2alpha1ClientDefaultOrganizationFlowsEnum.ClientCredentials }, result.Spec.Conf.DefaultOrganization.Flows); + Assert.IsNotNull(result.Spec.Conf.OidcLogout); + CollectionAssert.AreEqual(new[] { "https://example.com/logout" }, result.Spec.Conf.OidcLogout.BackchannelLogoutUrls); + Assert.AreEqual(V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.Custom, result.Spec.Conf.OidcLogout.BackchannelLogoutInitiators?.Mode); + CollectionAssert.AreEqual(new[] { V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.RpLogout }, result.Spec.Conf.OidcLogout.BackchannelLogoutInitiators?.SelectedInitiators); + } + + [TestMethod] + public void Converter_RevertConf_MapsClientSpecificFields_WithoutDirectJsonV2ToV1() + { + var source = new V2alpha1ClientEntity + { + Spec = + { + Find = new V2alpha1ClientFind { ClientId = "abc123", Name = "modern-app" }, + Conf = new V2alpha1ClientConf + { + Name = "modern-app", + ApplicationType = V2alpha1ClientAppTypeEnum.RegularWeb, + TokenEndpointAuthMethod = V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretPost, + ComplianceLevel = V2alpha1ClientComplianceLevelEnum.Fapi1AdvPkjPar, + OrganizationUsage = V2alpha1ClientOrganizationUsageEnum.Require, + OrganizationRequireBehavior = V2alpha1ClientOrganizationRequireBehaviorEnum.PostLoginPrompt, + RefreshToken = new V2alpha1ClientRefreshTokenConfiguration + { + RotationType = V2alpha1ClientRefreshTokenRotationTypeEnum.Rotating, + ExpirationType = V2alpha1ClientRefreshTokenExpirationTypeEnum.Expiring, + Leeway = 10, + TokenLifetime = 7200, + InfiniteTokenLifetime = false, + IdleTokenLifetime = 1800, + InfiniteIdleTokenLifetime = false, + }, + DefaultOrganization = new V2alpha1ClientDefaultOrganization + { + OrganizationId = "org_123", + Flows = [V2alpha1ClientDefaultOrganizationFlowsEnum.ClientCredentials], + }, + OidcLogout = new V2alpha1ClientOidcBackchannelLogoutSettings + { + BackchannelLogoutUrls = ["https://example.com/logout"], + BackchannelLogoutInitiators = new V2alpha1ClientOidcBackchannelLogoutInitiators + { + Mode = V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.Custom, + SelectedInitiators = [V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.RpLogout], + }, + }, + EncryptionKey = new V2alpha1ClientEncryptionKey + { + Cert = "cert", + Pub = "pub", + Subject = "subject", + }, + }, + }, + Status = + { + Id = "cli_123", + }, + }; + + var result = InvokeRevert(source); + + Assert.AreEqual("abc123", result.Spec.Find?.ClientId); + Assert.AreEqual("modern-app", result.Spec.Find?.Name); + Assert.AreEqual("cli_123", result.Status.Id); + Assert.AreEqual(V1ClientApplicationType.RegularWeb, result.Spec.Conf?.ApplicationType); + Assert.AreEqual(V1ClientTokenEndpointAuthMethod.ClientSecretPost, result.Spec.Conf?.TokenEndpointAuthMethod); + Assert.AreEqual(V1ClientComplianceLevel.Fapi1AdvPkjPar, result.Spec.Conf?.ComplianceLevel); + Assert.AreEqual(V1ClientOrganizationUsage.Require, result.Spec.Conf?.OrganizationUsage); + Assert.AreEqual(V1ClientOrganizationRequireBehavior.PostLoginPrompt, result.Spec.Conf?.OrganizationRequireBehavior); + Assert.IsNotNull(result.Spec.Conf?.RefreshToken); + Assert.AreEqual(V1ClientRefreshTokenRotationType.Rotating, result.Spec.Conf.RefreshToken.RotationType); + Assert.AreEqual(V1ClientRefreshTokenExpirationType.Expiring, result.Spec.Conf.RefreshToken.ExpirationType); + Assert.AreEqual(10, result.Spec.Conf.RefreshToken.Leeway); + Assert.IsNotNull(result.Spec.Conf.DefaultOrganization); + Assert.AreEqual("org_123", result.Spec.Conf.DefaultOrganization.OrganizationId); + CollectionAssert.AreEqual(new[] { V1ClientFlows.ClientCredentials }, result.Spec.Conf.DefaultOrganization.Flows); + Assert.IsNotNull(result.Spec.Conf.OidcLogout); + CollectionAssert.AreEqual(new[] { "https://example.com/logout" }, result.Spec.Conf.OidcLogout.BackchannelLogoutUrls); + Assert.AreEqual(V1ClientLogoutInitiatorModes.Custom, result.Spec.Conf.OidcLogout.BackchannelLogoutInitiators?.Mode); + CollectionAssert.AreEqual(new[] { V1ClientLogoutInitiators.RpLogout }, result.Spec.Conf.OidcLogout.BackchannelLogoutInitiators?.SelectedInitiators); + Assert.IsNotNull(result.Spec.Conf.EncryptionKey); + Assert.AreEqual("cert", result.Spec.Conf.EncryptionKey.Certificate); + Assert.AreEqual("pub", result.Spec.Conf.EncryptionKey.PublicKey); + Assert.AreEqual("subject", result.Spec.Conf.EncryptionKey.Subject); + } + + static V2alpha1ClientEntity InvokeConvert(V1Client source) + { + var converter = CreateConverter(); + var method = converter.GetType().GetMethod("Convert", BindingFlags.Instance | BindingFlags.Public); + Assert.IsNotNull(method); + return (V2alpha1ClientEntity)method!.Invoke(converter, [source])!; + } + + static V1Client InvokeRevert(V2alpha1ClientEntity source) + { + var converter = CreateConverter(); + var method = converter.GetType().GetMethod("Revert", BindingFlags.Instance | BindingFlags.Public); + Assert.IsNotNull(method); + return (V1Client)method!.Invoke(converter, [source])!; + } + + static object CreateConverter() + { + var converterType = Type.GetType("Alethic.Auth0.Operator.Converters.ClientConverter+V1ToV2alpha1, Alethic.Auth0.Operator"); + Assert.IsNotNull(converterType); + return Activator.CreateInstance(converterType!, nonPublic: true)!; + } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Tests/V2alpha1ConnectionControllerMappingTests.cs b/src/Alethic.Auth0.Operator.Tests/V2alpha1ConnectionControllerMappingTests.cs new file mode 100644 index 0000000..aac6b6a --- /dev/null +++ b/src/Alethic.Auth0.Operator.Tests/V2alpha1ConnectionControllerMappingTests.cs @@ -0,0 +1,591 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text.Json; + +using Alethic.Auth0.Operator.Controllers; +using Alethic.Auth0.Operator.Converters; +using Alethic.Auth0.Operator.Core.Models.Connection.V1; +using Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; +using Alethic.Auth0.Operator.Models; + +using Auth0.ManagementApi; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Alethic.Auth0.Operator.Tests +{ + + [TestClass] + [System.Runtime.Versioning.RequiresPreviewFeatures] + public class V2alpha1ConnectionControllerMappingTests + { + + [TestMethod] + public void FromApi_Null_ReturnsNull() + { + Assert.IsNull(V2alpha1ConnectionController.FromApi((GetConnectionResponseContent?)null)); + } + + [TestMethod] + public void FromApi_Connection_MapsScalarProperties() + { + var source = new GetConnectionResponseContent + { + Name = "test-conn", + DisplayName = "Test Connection", + Strategy = "auth0", + Realms = ["realm1", "realm2"], + IsDomainConnection = true, + ShowAsButton = false, + }; + + var result = V2alpha1ConnectionController.FromApi(source); + + Assert.IsNotNull(result); + Assert.AreEqual("test-conn", result.Name); + Assert.AreEqual("Test Connection", result.DisplayName); + Assert.AreEqual(V2alpha1ConnectionStrategy.Auth0, result.Strategy); + CollectionAssert.AreEqual(new[] { "realm1", "realm2" }, result.Realms); + Assert.AreEqual(true, result.IsDomainConnection); + Assert.AreEqual(false, result.ShowAsButton); + } + + [TestMethod] + public void FromApi_Connection_EnabledClientsIsNull() + { + var result = V2alpha1ConnectionController.FromApi(new GetConnectionResponseContent { Name = "x", Strategy = "auth0" }); + Assert.IsNotNull(result); + Assert.IsNull(result.EnabledClients); + } + + [TestMethod] + public void FromApi_Connection_NullStrategyOptions_AllStrategySpecificPropertiesNull() + { + var result = V2alpha1ConnectionController.FromApi(new GetConnectionResponseContent { Name = "x", Strategy = "auth0" }); + Assert.IsNotNull(result); + Assert.IsNull(result.Options?.Auth0); + Assert.IsNull(result.Options?.Oidc); + Assert.IsNull(result.Metadata); + } + + [TestMethod] + public void FromApi_Connection_MapsMetadata() + { + var source = new GetConnectionResponseContent + { + Name = "x", + Strategy = "auth0", + Metadata = new System.Collections.Generic.Dictionary { ["env"] = "prod" }, + }; + + var result = V2alpha1ConnectionController.FromApi(source); + Assert.IsNotNull(result); + Assert.IsNotNull(result.Metadata); + Assert.AreEqual("prod", result.Metadata["env"]?.ToString()); + } + + [TestMethod] + public void FromApi_Connection_NullStrategy_MapsNull() + { + var result = V2alpha1ConnectionController.FromApi(new GetConnectionResponseContent { Name = "no-strat" }); + Assert.IsNotNull(result); + Assert.IsNull(result.Strategy); + } + + [TestMethod] + public void ApplyToApi_ConnectionBase_MapsName() + { + var conf = new V2alpha1ConnectionConf { Name = "my-conn" }; + var req = new CreateConnectionRequestContent { Strategy = new ConnectionIdentityProviderEnum("auth0"), Name = "placeholder" }; + V2alpha1ConnectionController.ApplyToApi(conf, req); + Assert.AreEqual("my-conn", req.Name); + } + + [TestMethod] + public void ApplyToApi_ConnectionBase_MapsDisplayName() + { + var conf = new V2alpha1ConnectionConf { DisplayName = "My Conn" }; + var req = new CreateConnectionRequestContent { Strategy = new ConnectionIdentityProviderEnum("auth0"), Name = "conn" }; + V2alpha1ConnectionController.ApplyToApi(conf, req); + Assert.AreEqual("My Conn", req.DisplayName); + } + + [TestMethod] + public void ApplyToApi_ConnectionBase_MapsRealms() + { + var conf = new V2alpha1ConnectionConf { Realms = ["r1"] }; + var req = new CreateConnectionRequestContent { Strategy = new ConnectionIdentityProviderEnum("auth0"), Name = "conn" }; + V2alpha1ConnectionController.ApplyToApi(conf, req); + CollectionAssert.AreEqual(new[] { "r1" }, req.Realms?.ToList()); + } + + [TestMethod] + public void ApplyToApi_ConnectionBase_MapsIsDomainConnection() + { + var conf = new V2alpha1ConnectionConf { IsDomainConnection = true }; + var req = new CreateConnectionRequestContent { Strategy = new ConnectionIdentityProviderEnum("auth0"), Name = "conn" }; + V2alpha1ConnectionController.ApplyToApi(conf, req); + Assert.AreEqual(true, req.IsDomainConnection); + } + + [TestMethod] + public void ApplyToApi_ConnectionBase_MapsShowAsButton() + { + var conf = new V2alpha1ConnectionConf { ShowAsButton = true }; + var req = new CreateConnectionRequestContent { Strategy = new ConnectionIdentityProviderEnum("auth0"), Name = "conn" }; + V2alpha1ConnectionController.ApplyToApi(conf, req); + Assert.AreEqual(true, req.ShowAsButton); + } + + [TestMethod] + public void ApplyToApi_ConnectionBase_NullFieldsLeaveTargetUnchanged() + { + var conf = new V2alpha1ConnectionConf(); + var req = new CreateConnectionRequestContent { Strategy = new ConnectionIdentityProviderEnum("auth0"), Name = "original" }; + V2alpha1ConnectionController.ApplyToApi(conf, req); + Assert.AreEqual("original", req.Name); + } + + [TestMethod] + public void FromApi_DecryptionKey_PrivateKey_MapsCustomProperty() + { + var source = ConnectionDecryptionKeySaml.FromString("pem-value"); + + var result = V2alpha1ConnectionController.FromApi(source); + + Assert.IsNotNull(result); + Assert.AreEqual("pem-value", result.PrivateKey); + Assert.IsNull(result.KeyPair); + } + + [TestMethod] + public void FromApi_DecryptionKey_KeyPair_MapsCustomProperty() + { + var source = ConnectionDecryptionKeySaml.FromConnectionDecryptionKeySamlCert( + new ConnectionDecryptionKeySamlCert + { + Cert = "cert-value", + Key = "key-value", + }); + + var result = V2alpha1ConnectionController.FromApi(source); + + Assert.IsNotNull(result); + Assert.IsNull(result.PrivateKey); + Assert.IsNotNull(result.KeyPair); + Assert.AreEqual("cert-value", result.KeyPair.Cert); + Assert.AreEqual("key-value", result.KeyPair.Key); + } + + [TestMethod] + public void ApplyToApi_SamlOptions_MapsPrivateKeyDecryptionKey() + { + var options = V2alpha1ConnectionController.ToApi( + new V2alpha1ConnectionOptionsSaml + { + SignInEndpoint = "https://idp.example/signin", + DecryptionKey = new V2alpha1ConnectionDecryptionKeySaml + { + PrivateKey = "pem-value", + }, + }); + + Assert.IsNotNull(options); + Assert.IsNotNull(options.DecryptionKey); + Assert.IsTrue(options.DecryptionKey.IsString()); + Assert.AreEqual("pem-value", options.DecryptionKey.AsString()); + } + + [TestMethod] + public void ApplyToApi_PingFederateOptions_MapsKeyPairDecryptionKey() + { + var options = V2alpha1ConnectionController.ToApi( + new V2alpha1ConnectionOptionsPingFederate + { + PingFederateBaseUrl = "https://pingfed.example", + DecryptionKey = new V2alpha1ConnectionDecryptionKeySaml + { + KeyPair = new V2alpha1ConnectionDecryptionKeySamlCert + { + Cert = "cert-value", + Key = "key-value", + }, + }, + }); + + Assert.IsNotNull(options); + Assert.IsNotNull(options.DecryptionKey); + Assert.IsTrue(options.DecryptionKey.IsConnectionDecryptionKeySamlCert()); + var cert = options.DecryptionKey.AsConnectionDecryptionKeySamlCert(); + Assert.AreEqual("cert-value", cert.Cert); + Assert.AreEqual("key-value", cert.Key); + } + + [TestMethod] + public void FromApi_GitHub_MapsUpstreamParams() + { + var source = new ConnectionOptionsGitHub + { + UpstreamParams = global::Auth0.ManagementApi.Core.Optional?>.Of( + new Dictionary + { + ["login_hint"] = ConnectionUpstreamAdditionalProperties.FromConnectionUpstreamValue( + new ConnectionUpstreamValue { Value = "user@example.com" }), + }), + }; + + var result = V2alpha1ConnectionController.FromApi(source); + + Assert.IsNotNull(result?.UpstreamParams); + Assert.IsTrue(result.UpstreamParams.TryGetValue("login_hint", out var value)); + Assert.AreEqual("user@example.com", value?.Value); + Assert.IsNull(value?.Alias); + } + + [TestMethod] + public void FromApi_PingFederate_MapsUpstreamParams() + { + var source = new ConnectionOptionsPingFederate + { + PingFederateBaseUrl = "https://pingfed.example", + UpstreamParams = global::Auth0.ManagementApi.Core.Optional?>.Of( + new Dictionary + { + ["resource"] = ConnectionUpstreamAdditionalProperties.FromConnectionUpstreamAlias( + new ConnectionUpstreamAlias { Alias = ConnectionUpstreamAliasEnum.Resource }), + }), + }; + + var result = V2alpha1ConnectionController.FromApi(source); + + Assert.IsNotNull(result?.UpstreamParams); + Assert.IsTrue(result.UpstreamParams.TryGetValue("resource", out var value)); + Assert.AreEqual(V2alpha1ConnectionUpstreamAliasEnum.Resource, value?.Alias); + Assert.IsNull(value?.Value); + } + + [TestMethod] + public void FromApi_Facebook_MapsUpstreamParams() + { + var source = new ConnectionOptionsFacebook + { + UpstreamParams = new Dictionary + { + ["prompt"] = ConnectionUpstreamAdditionalProperties.FromConnectionUpstreamAlias( + new ConnectionUpstreamAlias { Alias = ConnectionUpstreamAliasEnum.Prompt }), + }, + }; + + var result = V2alpha1ConnectionController.FromApi(source); + + Assert.IsNotNull(result?.UpstreamParams); + Assert.IsTrue(result.UpstreamParams.TryGetValue("prompt", out var value)); + Assert.AreEqual(V2alpha1ConnectionUpstreamAliasEnum.Prompt, value?.Alias); + Assert.IsNull(value?.Value); + } + + [TestMethod] + public void FromApi_Oidc_MapsOidcMetadata() + { + var source = new ConnectionOptionsOidc + { + ClientId = "client-id", + OidcMetadata = new ConnectionOptionsOidcMetadata + { + AuthorizationEndpoint = "https://issuer.example/authorize", + Issuer = "https://issuer.example", + JwksUri = "https://issuer.example/jwks", + ClaimsSupported = ["sub", "email"], + ScopesSupported = global::Auth0.ManagementApi.Core.Optional?>.Of(["openid", "profile"]), + }, + }; + + var result = V2alpha1ConnectionController.FromApi(source); + + Assert.IsNotNull(result?.OidcMetadata); + Assert.AreEqual("https://issuer.example/authorize", result.OidcMetadata.AuthorizationEndpoint); + CollectionAssert.AreEqual(new[] { "sub", "email" }, result.OidcMetadata.ClaimsSupported); + CollectionAssert.AreEqual(new[] { "openid", "profile" }, result.OidcMetadata.ScopesSupported); + } + + [TestMethod] + public void ApplyToApi_Oidc_MapsOidcMetadata() + { + var options = V2alpha1ConnectionController.ToApi( + new V2alpha1ConnectionOptionsOidc + { + ClientId = "client-id", + ClientSecret = "client-secret", + OidcMetadata = new V2alpha1ConnectionOptionsOidcMetadata + { + AuthorizationEndpoint = "https://issuer.example/authorize", + ClaimsSupported = ["sub", "email"], + ScopesSupported = ["openid", "profile"], + }, + }); + + Assert.IsNotNull(options.OidcMetadata); + Assert.AreEqual("https://issuer.example/authorize", options.OidcMetadata.AuthorizationEndpoint); + CollectionAssert.AreEqual(new[] { "sub", "email" }, options.OidcMetadata.ClaimsSupported?.ToArray()); + Assert.IsTrue(options.OidcMetadata.ScopesSupported.IsDefined); + CollectionAssert.AreEqual(new[] { "openid", "profile" }, options.OidcMetadata.ScopesSupported.Value?.ToArray()); + } + + [TestMethod] + public void FromApi_Okta_MapsOidcMetadata() + { + var source = new ConnectionOptionsOkta + { + ClientId = "client-id", + OidcMetadata = new ConnectionOptionsOidcMetadata + { + AuthorizationEndpoint = "https://issuer.example/authorize", + Issuer = "https://issuer.example", + JwksUri = "https://issuer.example/jwks", + ResponseTypesSupported = ["code", "id_token"], + }, + }; + + var result = V2alpha1ConnectionController.FromApi(source); + + Assert.IsNotNull(result?.OidcMetadata); + Assert.AreEqual("https://issuer.example", result.OidcMetadata.Issuer); + CollectionAssert.AreEqual(new[] { "code", "id_token" }, result.OidcMetadata.ResponseTypesSupported); + } + + [TestMethod] + public void Converter_ConvertConf_SamlDecryptionKey_MapsPrivateKey() + { + var source = new V1Connection + { + Spec = + { + Conf = new V1ConnectionConf + { + Name = "saml-conn", + Strategy = "samlp", + Options = JsonSerializer.Deserialize(""" + { + "decryptionKey": "pem-value" + } + """) + } + } + }; + + var result = InvokeConvert(source); + + Assert.IsNotNull(result.Spec.Conf?.Options?.Saml?.DecryptionKey); + Assert.AreEqual("pem-value", result.Spec.Conf.Options.Saml.DecryptionKey.PrivateKey); + Assert.IsNull(result.Spec.Conf.Options.Saml.DecryptionKey.KeyPair); + } + + [TestMethod] + public void Converter_ConvertConf_OidcMetadata_MapsThroughAuth0ApiModel() + { + var source = new V1Connection + { + Spec = + { + Conf = new V1ConnectionConf + { + Name = "oidc-conn", + Strategy = "oidc", + Options = JsonSerializer.Deserialize(""" + { + "client_id": "client-id", + "issuer": "https://issuer.example", + "jwks_uri": "https://issuer.example/jwks.json", + "oidc_metadata": { + "authorization_endpoint": "https://issuer.example/authorize", + "issuer": "https://issuer.example", + "jwks_uri": "https://issuer.example/jwks.json", + "claims_supported": ["sub", "email"], + "scopes_supported": ["openid", "profile"] + } + } + """) + } + } + }; + + var result = InvokeConvert(source); + var metadata = result.Spec.Conf?.Options?.Oidc?.OidcMetadata; + + Assert.IsNotNull(metadata); + Assert.AreEqual("https://issuer.example/authorize", metadata.AuthorizationEndpoint); + CollectionAssert.AreEqual(new[] { "sub", "email" }, metadata.ClaimsSupported); + CollectionAssert.AreEqual(new[] { "openid", "profile" }, metadata.ScopesSupported); + } + + [TestMethod] + public void Converter_RevertConf_SamlDecryptionKey_PrefersPrivateKey() + { + var source = new V2alpha1Connection + { + Spec = + { + Conf = new V2alpha1ConnectionConf + { + Name = "saml-conn", + Strategy = V2alpha1ConnectionStrategy.Saml, + Options = new V2alpha1ConnectionOptions + { + Saml = new V2alpha1ConnectionOptionsSaml + { + DecryptionKey = new V2alpha1ConnectionDecryptionKeySaml + { + PrivateKey = "pem-value", + KeyPair = new V2alpha1ConnectionDecryptionKeySamlCert + { + Cert = "cert-value", + Key = "key-value", + }, + }, + }, + }, + } + } + }; + + var result = InvokeRevert(source); + var decryptionKey = GetAdditionalProperty(result.Spec.Conf?.Options, "decryptionKey"); + + Assert.AreEqual(JsonValueKind.String, decryptionKey.ValueKind); + Assert.AreEqual("pem-value", decryptionKey.GetString()); + } + + [TestMethod] + public void Converter_RevertConf_OidcMetadata_MapsThroughAuth0ApiModel() + { + var source = new V2alpha1Connection + { + Spec = + { + Conf = new V2alpha1ConnectionConf + { + Name = "oidc-conn", + Strategy = V2alpha1ConnectionStrategy.Oidc, + Options = new V2alpha1ConnectionOptions + { + Oidc = new V2alpha1ConnectionOptionsOidc + { + ClientId = "client-id", + OidcMetadata = new V2alpha1ConnectionOptionsOidcMetadata + { + AuthorizationEndpoint = "https://issuer.example/authorize", + ClaimsSupported = ["sub", "email"], + Issuer = "https://issuer.example", + JwksUri = "https://issuer.example/jwks.json", + ScopesSupported = ["openid", "profile"], + }, + }, + }, + } + } + }; + + var result = InvokeRevert(source); + var oidcMetadata = GetAdditionalProperty(result.Spec.Conf?.Options, "oidc_metadata"); + + Assert.AreEqual("https://issuer.example/authorize", oidcMetadata.GetProperty("authorization_endpoint").GetString()); + CollectionAssert.AreEqual(new[] { "sub", "email" }, oidcMetadata.GetProperty("claims_supported").EnumerateArray().Select(static i => i.GetString()).ToArray()); + CollectionAssert.AreEqual(new[] { "openid", "profile" }, oidcMetadata.GetProperty("scopes_supported").EnumerateArray().Select(static i => i.GetString()).ToArray()); + } + + [TestMethod] + public void Converter_RevertConf_PingFederateDecryptionKey_UsesKeyPair() + { + var source = new V2alpha1Connection + { + Spec = + { + Conf = new V2alpha1ConnectionConf + { + Name = "pingfed-conn", + Strategy = V2alpha1ConnectionStrategy.PingFederate, + Options = new V2alpha1ConnectionOptions + { + PingFederate = new V2alpha1ConnectionOptionsPingFederate + { + PingFederateBaseUrl = "https://pingfed.example", + DecryptionKey = new V2alpha1ConnectionDecryptionKeySaml + { + KeyPair = new V2alpha1ConnectionDecryptionKeySamlCert + { + Cert = "cert-value", + Key = "key-value", + }, + }, + }, + }, + } + } + }; + + var result = InvokeRevert(source); + var decryptionKey = GetAdditionalProperty(result.Spec.Conf?.Options, "decryptionKey"); + + Assert.IsFalse(decryptionKey.TryGetProperty("privateKey", out JsonElement _)); + Assert.AreEqual("cert-value", decryptionKey.GetProperty("cert").GetString()); + Assert.AreEqual("key-value", decryptionKey.GetProperty("key").GetString()); + } + + [TestMethod] + public void Roundtrip_ScalarProperties() + { + var source = new GetConnectionResponseContent + { + Name = "roundtrip", + DisplayName = "Roundtrip", + Strategy = "auth0", + IsDomainConnection = false, + ShowAsButton = true, + }; + + var conf = V2alpha1ConnectionController.FromApi(source)!; + var req = new CreateConnectionRequestContent { Strategy = new ConnectionIdentityProviderEnum(System.Text.Json.JsonSerializer.Serialize(conf.Strategy).Trim('"')), Name = conf.Name! }; + V2alpha1ConnectionController.ApplyToApi(conf, req); + + Assert.AreEqual(source.Name, req.Name); + Assert.AreEqual(source.DisplayName, req.DisplayName); + Assert.AreEqual(source.IsDomainConnection, req.IsDomainConnection); + Assert.AreEqual(source.ShowAsButton, req.ShowAsButton); + } + + static V2alpha1Connection InvokeConvert(V1Connection source) + { + var converter = CreateConverter(); + var method = converter.GetType().GetMethod("Convert", BindingFlags.Instance | BindingFlags.Public); + Assert.IsNotNull(method); + return (V2alpha1Connection)method!.Invoke(converter, [source])!; + } + + static V1Connection InvokeRevert(V2alpha1Connection source) + { + var converter = CreateConverter(); + var method = converter.GetType().GetMethod("Revert", BindingFlags.Instance | BindingFlags.Public); + Assert.IsNotNull(method); + return (V1Connection)method!.Invoke(converter, [source])!; + } + + static object CreateConverter() + { + var converterType = Type.GetType("Alethic.Auth0.Operator.Converters.ConnectionConverter+V1ToV2alpha1, Alethic.Auth0.Operator"); + Assert.IsNotNull(converterType); + return Activator.CreateInstance(converterType!, nonPublic: true)!; + } + + static JsonElement GetAdditionalProperty(V1ConnectionOptions? options, string propertyName) + { + Assert.IsNotNull(options?.AdditionalProperties); + Assert.IsTrue(options.AdditionalProperties.TryGetValue(propertyName, out var value)); + Assert.IsInstanceOfType(value); + return (JsonElement)value!; + } + + } + +} diff --git a/src/Alethic.Auth0.Operator.Tests/V2alpha1TenantControllerMappingTests.cs b/src/Alethic.Auth0.Operator.Tests/V2alpha1TenantControllerMappingTests.cs index df60800..38a5423 100644 --- a/src/Alethic.Auth0.Operator.Tests/V2alpha1TenantControllerMappingTests.cs +++ b/src/Alethic.Auth0.Operator.Tests/V2alpha1TenantControllerMappingTests.cs @@ -1,8 +1,7 @@ using Alethic.Auth0.Operator.Controllers; using Alethic.Auth0.Operator.Core.Models.Tenant.V2alpha1; -using Auth0.ManagementApi.Models; -using Auth0.ManagementApi.Models.Prompts; +using Auth0.ManagementApi; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -18,13 +17,13 @@ public class V2alpha1TenantControllerMappingTests [TestMethod] public void FromApi_Prompt_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((Prompt?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((GetSettingsResponseContent?)null)); } [TestMethod] public void FromApi_Branding_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((Branding?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((GetBrandingResponseContent?)null)); } [TestMethod] @@ -36,49 +35,49 @@ public void FromApi_BrandingColors_Null_Returns_Null() [TestMethod] public void FromApi_TenantSettings_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((TenantSettings?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((GetTenantSettingsResponseContent?)null)); } [TestMethod] public void FromApi_TenantMtls_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((TenantMtls?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((TenantSettingsMtls?)null)); } [TestMethod] public void FromApi_SessionCookie_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((SessionCookie?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((SessionCookieSchema?)null)); } [TestMethod] public void FromApi_TenantGuardianMfaPage_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((TenantGuardianMfaPage?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((TenantSettingsGuardianPage?)null)); } [TestMethod] public void FromApi_TenantErrorPage_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((TenantErrorPage?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((TenantSettingsErrorPage?)null)); } [TestMethod] public void FromApi_TenantDeviceFlow_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((TenantDeviceFlow?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((TenantSettingsDeviceFlow?)null)); } [TestMethod] public void FromApi_TenantChangePassword_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((TenantChangePassword?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((TenantSettingsPasswordPage?)null)); } [TestMethod] public void FromApi_TenantFlags_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((TenantFlags?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((TenantSettingsFlags?)null)); } // ──────────────────────── FromApi string UniversalLoginExperience ───────── @@ -86,31 +85,28 @@ public void FromApi_TenantFlags_Null_Returns_Null() [TestMethod] [DataRow("new", V2alpha1TenantUniversalLoginExperience.New)] [DataRow("classic", V2alpha1TenantUniversalLoginExperience.Classic)] - public void FromApi_UniversalLoginExperience_MapsCorrectly(string input, V2alpha1TenantUniversalLoginExperience expected) + public void FromApi_UniversalLoginExperience_MapsCorrectly(string inputValue, V2alpha1TenantUniversalLoginExperience expected) { - Assert.AreEqual(expected, V2alpha1TenantController.FromApi(input)); + Assert.AreEqual(expected, V2alpha1TenantController.FromApi(new UniversalLoginExperienceEnum(inputValue))); } [TestMethod] public void FromApi_UniversalLoginExperience_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((string?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((UniversalLoginExperienceEnum?)null)); } // ──────────────────────── FromApi TenantDeviceFlowCharset ───────────────── [TestMethod] - [DataRow(TenantDeviceFlowCharset.Base20, V2alpha1TenantCharset.Base20)] - [DataRow(TenantDeviceFlowCharset.Digits, V2alpha1TenantCharset.Digits)] - public void FromApi_TenantDeviceFlowCharset_MapsCorrectly(TenantDeviceFlowCharset input, V2alpha1TenantCharset expected) - { - Assert.AreEqual(expected, V2alpha1TenantController.FromApi((TenantDeviceFlowCharset?)input)); - } + public void FromApi_TenantDeviceFlowCharset_Base20() => Assert.AreEqual(V2alpha1TenantCharset.Base20, V2alpha1TenantController.FromApi((TenantSettingsDeviceFlowCharset?)new TenantSettingsDeviceFlowCharset(TenantSettingsDeviceFlowCharset.Values.Base20))); + [TestMethod] + public void FromApi_TenantDeviceFlowCharset_Digits() => Assert.AreEqual(V2alpha1TenantCharset.Digits, V2alpha1TenantController.FromApi((TenantSettingsDeviceFlowCharset?)new TenantSettingsDeviceFlowCharset(TenantSettingsDeviceFlowCharset.Values.Digits))); [TestMethod] public void FromApi_TenantDeviceFlowCharset_Null_Returns_Null() { - Assert.IsNull(V2alpha1TenantController.FromApi((TenantDeviceFlowCharset?)null)); + Assert.IsNull(V2alpha1TenantController.FromApi((TenantSettingsDeviceFlowCharset?)null)); } // ──────────────────────── FromApi value objects ─────────────────────────── @@ -118,7 +114,7 @@ public void FromApi_TenantDeviceFlowCharset_Null_Returns_Null() [TestMethod] public void FromApi_Prompt_MapsProperties() { - var source = new Prompt { IdentifierFirst = true, WebAuthnPlatformFirstFactor = false }; + var source = new GetSettingsResponseContent { IdentifierFirst = true, WebauthnPlatformFirstFactor = false }; var result = V2alpha1TenantController.FromApi(source); Assert.IsNotNull(result); Assert.AreEqual(true, result.IdentifierFirst); @@ -128,7 +124,7 @@ public void FromApi_Prompt_MapsProperties() [TestMethod] public void FromApi_Branding_MapsProperties() { - var source = new Branding { LogoUrl = "https://example.com/logo.png", FaviconUrl = "https://example.com/favicon.ico" }; + var source = new GetBrandingResponseContent { LogoUrl = "https://example.com/logo.png", FaviconUrl = "https://example.com/favicon.ico" }; var result = V2alpha1TenantController.FromApi(source); Assert.IsNotNull(result); Assert.AreEqual("https://example.com/logo.png", result.LogoUrl); @@ -148,7 +144,7 @@ public void FromApi_BrandingColors_MapsProperties() [TestMethod] public void FromApi_TenantMtls_MapsProperties() { - var source = new TenantMtls { EnableEndpointAliases = true }; + var source = new TenantSettingsMtls { EnableEndpointAliases = true }; var result = V2alpha1TenantController.FromApi(source); Assert.IsNotNull(result); Assert.AreEqual(true, result.EnableEndpointAliases); @@ -157,7 +153,7 @@ public void FromApi_TenantMtls_MapsProperties() [TestMethod] public void FromApi_SessionCookie_MapsMode() { - var source = new SessionCookie { Mode = "persistent" }; + var source = new SessionCookieSchema { Mode = new SessionCookieModeEnum("persistent") }; var result = V2alpha1TenantController.FromApi(source); Assert.IsNotNull(result); Assert.AreEqual("persistent", result.Mode); @@ -166,7 +162,7 @@ public void FromApi_SessionCookie_MapsMode() [TestMethod] public void FromApi_TenantGuardianMfaPage_MapsProperties() { - var source = new TenantGuardianMfaPage { Enabled = true, Html = "" }; + var source = new TenantSettingsGuardianPage { Enabled = true, Html = "" }; var result = V2alpha1TenantController.FromApi(source); Assert.IsNotNull(result); Assert.AreEqual(true, result.Enabled); @@ -176,7 +172,7 @@ public void FromApi_TenantGuardianMfaPage_MapsProperties() [TestMethod] public void FromApi_TenantErrorPage_MapsProperties() { - var source = new TenantErrorPage { ShowLogLink = true, Url = "https://example.com/error", Html = "" }; + var source = new TenantSettingsErrorPage { ShowLogLink = true, Url = "https://example.com/error", Html = "" }; var result = V2alpha1TenantController.FromApi(source); Assert.IsNotNull(result); Assert.AreEqual(true, result.ShowLogLink); @@ -187,7 +183,7 @@ public void FromApi_TenantErrorPage_MapsProperties() [TestMethod] public void FromApi_TenantDeviceFlow_MapsMask() { - var source = new TenantDeviceFlow { Mask = "***-***", Charset = TenantDeviceFlowCharset.Digits }; + var source = new TenantSettingsDeviceFlow { Mask = "***-***", Charset = new TenantSettingsDeviceFlowCharset(TenantSettingsDeviceFlowCharset.Values.Digits) }; var result = V2alpha1TenantController.FromApi(source); Assert.IsNotNull(result); Assert.AreEqual("***-***", result.Mask); @@ -197,7 +193,7 @@ public void FromApi_TenantDeviceFlow_MapsMask() [TestMethod] public void FromApi_TenantChangePassword_MapsProperties() { - var source = new TenantChangePassword { Enabled = true, Html = "" }; + var source = new TenantSettingsPasswordPage { Enabled = true, Html = "" }; var result = V2alpha1TenantController.FromApi(source); Assert.IsNotNull(result); Assert.AreEqual(true, result.Enabled); @@ -207,7 +203,7 @@ public void FromApi_TenantChangePassword_MapsProperties() [TestMethod] public void FromApi_TenantFlags_MapsBoolProperties() { - var source = new TenantFlags { EnableSSO = true, EnablePipeline2 = false, RemoveAlgFromJwks = true }; + var source = new TenantSettingsFlags { EnableSso = true, EnablePipeline2 = false, RemoveAlgFromJwks = true }; var result = V2alpha1TenantController.FromApi(source); Assert.IsNotNull(result); Assert.AreEqual(true, result.EnableSSO); @@ -220,37 +216,30 @@ public void FromApi_TenantFlags_MapsBoolProperties() [TestMethod] [DataRow(V2alpha1TenantUniversalLoginExperience.New, "new")] [DataRow(V2alpha1TenantUniversalLoginExperience.Classic, "classic")] - public void ToApi_UniversalLoginExperience_MapsCorrectly(V2alpha1TenantUniversalLoginExperience input, string expected) + public void ToApi_UniversalLoginExperience_MapsCorrectly(V2alpha1TenantUniversalLoginExperience input, string expectedValue) { - Assert.AreEqual(expected, V2alpha1TenantController.ToApi(input)); + Assert.AreEqual(expectedValue, V2alpha1TenantController.ToApi(input).Value); } [TestMethod] - [DataRow(V2alpha1TenantCharset.Base20, TenantDeviceFlowCharset.Base20)] - [DataRow(V2alpha1TenantCharset.Digits, TenantDeviceFlowCharset.Digits)] - public void ToApi_TenantCharset_MapsCorrectly(V2alpha1TenantCharset input, TenantDeviceFlowCharset expected) - { - Assert.AreEqual(expected, V2alpha1TenantController.ToApi(input)); - } + public void ToApi_TenantCharset_Base20() => Assert.AreEqual(TenantSettingsDeviceFlowCharset.Values.Base20, V2alpha1TenantController.ToApi(V2alpha1TenantCharset.Base20).Value); + [TestMethod] + public void ToApi_TenantCharset_Digits() => Assert.AreEqual(TenantSettingsDeviceFlowCharset.Values.Digits, V2alpha1TenantController.ToApi(V2alpha1TenantCharset.Digits).Value); // ──────────────────────── Roundtrip tests ───────────────────────────────── [TestMethod] - [DataRow(TenantDeviceFlowCharset.Base20)] - [DataRow(TenantDeviceFlowCharset.Digits)] - public void TenantDeviceFlowCharset_Roundtrip(TenantDeviceFlowCharset input) - { - var op = V2alpha1TenantController.FromApi((TenantDeviceFlowCharset?)input)!.Value; - Assert.AreEqual(input, V2alpha1TenantController.ToApi(op)); - } + public void TenantDeviceFlowCharset_Roundtrip_Base20() { var v = new TenantSettingsDeviceFlowCharset(TenantSettingsDeviceFlowCharset.Values.Base20); var op = V2alpha1TenantController.FromApi((TenantSettingsDeviceFlowCharset?)v)!.Value; Assert.AreEqual(v.Value, V2alpha1TenantController.ToApi(op).Value); } + [TestMethod] + public void TenantDeviceFlowCharset_Roundtrip_Digits() { var v = new TenantSettingsDeviceFlowCharset(TenantSettingsDeviceFlowCharset.Values.Digits); var op = V2alpha1TenantController.FromApi((TenantSettingsDeviceFlowCharset?)v)!.Value; Assert.AreEqual(v.Value, V2alpha1TenantController.ToApi(op).Value); } [TestMethod] [DataRow("new")] [DataRow("classic")] - public void UniversalLoginExperience_Roundtrip(string input) + public void UniversalLoginExperience_Roundtrip(string inputValue) { - var op = V2alpha1TenantController.FromApi(input)!.Value; - Assert.AreEqual(input, V2alpha1TenantController.ToApi(op)); + var op = V2alpha1TenantController.FromApi(new UniversalLoginExperienceEnum(inputValue))!.Value; + Assert.AreEqual(inputValue, V2alpha1TenantController.ToApi(op).Value); } } diff --git a/src/Alethic.Auth0.Operator/Alethic.Auth0.Operator.csproj b/src/Alethic.Auth0.Operator/Alethic.Auth0.Operator.csproj index c94d0ac..206100a 100644 --- a/src/Alethic.Auth0.Operator/Alethic.Auth0.Operator.csproj +++ b/src/Alethic.Auth0.Operator/Alethic.Auth0.Operator.csproj @@ -18,14 +18,14 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/Alethic.Auth0.Operator/Controllers/ControllerBase.cs b/src/Alethic.Auth0.Operator/Controllers/ControllerBase.cs index 7ef45c9..2d3d4e8 100644 --- a/src/Alethic.Auth0.Operator/Controllers/ControllerBase.cs +++ b/src/Alethic.Auth0.Operator/Controllers/ControllerBase.cs @@ -1,13 +1,9 @@ using System; -using System.Diagnostics.CodeAnalysis; -using System.IO; using System.Net; using System.Text; -using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Alethic.Auth0.Operator.Core.Extensions; using Alethic.Auth0.Operator.Core.Models; using Alethic.Auth0.Operator.Models; using Alethic.Auth0.Operator.Options; @@ -30,8 +26,6 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using Newtonsoft.Json; - namespace Alethic.Auth0.Operator.Controllers { @@ -45,9 +39,6 @@ public abstract class ControllerBase where TLastConf : class { - static readonly Newtonsoft.Json.JsonSerializer _newtonsoftJsonSerializer = Newtonsoft.Json.JsonSerializer.CreateDefault(); - static readonly JsonSerializerOptions _jsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web) { Converters = { new SimplePrimitiveHashtableConverter() } }; - readonly IKubernetesClient _kube; readonly IMemoryCache _cache; readonly IOptions _options; @@ -242,7 +233,7 @@ public ControllerBase(IKubernetesClient kube, IMemoryCache cache, IOptions GetTenantApiClientAsync(V2alpha1Tenan throw new RetryException($"Tenant {tenant.Namespace()}/{tenant.Name()} failed to retrieve management API token."); // contact API using token and domain - var api = new ManagementApiClient(authToken.AccessToken, new Uri($"https://{domain}/api/v2/"), new HttpClientManagementConnection()); + var api = new ManagementApiClient(authToken.AccessToken, new ClientOptions { BaseUrl = $"https://{domain}/api/v2/" }); // expire cache entry slightly before token expiration to allow for refresh var expire = TimeSpan.FromSeconds(authToken.ExpiresIn); @@ -438,52 +429,6 @@ await _kube.CreateAsync(new Eventsv1Event() }, cancellationToken); } - /// - /// Transforms the given Newtonsoft JSON serializable object to a System.Text.Json serializable object. - /// - /// - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(from))] - protected static TTo? TransformToNewtonsoftJson(TFrom? from) - where TFrom : class - where TTo : class - { - if (from == null) - return null; - - var to = _newtonsoftJsonSerializer.Deserialize(new JsonTextReader(new StringReader(System.Text.Json.JsonSerializer.Serialize(from, _jsonSerializerOptions)))); - if (to is null) - throw new InvalidOperationException(); - - return to; - } - - /// - /// Transforms the given Newtonsoft JSON serializable object to a System.Text.Json serializable object. - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(from))] - protected static TTo? TransformToSystemTextJson(object? from) - where TTo : class - { - if (from == null) - return null; - - using var w = new StringWriter(); - _newtonsoftJsonSerializer.Serialize(w, from); - - var to = System.Text.Json.JsonSerializer.Deserialize(w.ToString(), _jsonSerializerOptions); - if (to is null) - throw new InvalidOperationException(); - - return to; - } - /// /// Implement this method to attempt the reconcillation. /// diff --git a/src/Alethic.Auth0.Operator/Controllers/V1ClientController.cs b/src/Alethic.Auth0.Operator/Controllers/V1ClientController.cs deleted file mode 100644 index b0a9554..0000000 --- a/src/Alethic.Auth0.Operator/Controllers/V1ClientController.cs +++ /dev/null @@ -1,1333 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -using Alethic.Auth0.Operator.Core.Models.Client.V1; -using Alethic.Auth0.Operator.Models; -using Alethic.Auth0.Operator.Options; - -using Auth0.Core.Exceptions; -using Auth0.ManagementApi; -using Auth0.ManagementApi.Models; - -using Newtonsoft.Json.Linq; - -using k8s.Models; - -using KubeOps.Abstractions.Entities; -using KubeOps.Abstractions.Rbac; -using KubeOps.Abstractions.Reconciliation.Controller; -using KubeOps.KubernetesClient; - -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace Alethic.Auth0.Operator.Controllers -{ - - [EntityRbac(typeof(V1Client), Verbs = RbacVerb.All)] - [EntityRbac(typeof(V1Secret), Verbs = RbacVerb.All)] - [EntityRbac(typeof(V2alpha1Tenant), Verbs = RbacVerb.List | RbacVerb.Get)] - [EntityRbac(typeof(V1Secret), Verbs = RbacVerb.List | RbacVerb.Get)] - [EntityRbac(typeof(Eventsv1Event), Verbs = RbacVerb.All)] - public class V1ClientController : - V1TenantEntityInstanceController, - IEntityController - { - - /// - /// Transforms the Auth0 Management API client model to the operator's client configuration model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientConf? FromApi(Client? source) => source is null ? null : new() - { - AllowedClients = source.AllowedClients?.ToArray(), - AllowedLogoutUrls = source.AllowedLogoutUrls?.ToArray(), - AllowedOrigins = source.AllowedOrigins?.ToArray(), - WebOrigins = source.WebOrigins?.ToArray(), - InitiateLoginUri = source.InitiateLoginUri, - Callbacks = source.Callbacks?.ToArray(), - ClientAliases = source.ClientAliases?.ToArray(), - ClientMetaData = source.ClientMetaData, - IsCustomLoginPageOn = source.IsCustomLoginPageOn, - IsFirstParty = source.IsFirstParty, - CustomLoginPage = source.CustomLoginPage, - CustomLoginPagePreview = source.CustomLoginPagePreview, - FormTemplate = source.FormTemplate, - GrantTypes = source.GrantTypes?.ToArray(), - Name = source.Name, - Description = source.Description, - LogoUri = source.LogoUri, - OidcConformant = source.OidcConformant, - Sso = source.Sso, - CrossOriginAuthentication = source.CrossOriginAuthentication, - RequirePushedAuthorizationRequests = source.RequirePushedAuthorizationRequests, - RequireProofOfPossession = source.RequireProofOfPossession, - AddOns = FromApi(source.AddOns), - ApplicationType = FromApi(source.ApplicationType), - ComplianceLevel = FromApi(source.ComplianceLevel), - DefaultOrganization = FromApi(source.DefaultOrganization), - EncryptionKey = FromApi(source.EncryptionKey), - JwtConfiguration = FromApi(source.JwtConfiguration), - Mobile = FromApi(source.Mobile), - OidcLogout = FromApi(source.OidcLogout), - OrganizationRequireBehavior = FromApi(source.OrganizationRequireBehavior), - OrganizationUsage = FromApi(source.OrganizationUsage), - RefreshToken = FromApi(source.RefreshToken), - ResourceServers = source.ResourceServers?.Select(i => FromApi(i)).ToArray(), - SigningKeys = source.SigningKeys?.Select(i => FromApi(i)).ToArray(), - TokenEndpointAuthMethod = FromApi(source.TokenEndpointAuthMethod), - }; - - /// - /// Transforms the token endpoint authentication method from the API model to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientTokenEndpointAuthMethod? FromApi(TokenEndpointAuthMethod? source) => source switch - { - TokenEndpointAuthMethod.None => V1ClientTokenEndpointAuthMethod.None, - TokenEndpointAuthMethod.ClientSecretPost => V1ClientTokenEndpointAuthMethod.ClientSecretPost, - TokenEndpointAuthMethod.ClientSecretBasic => V1ClientTokenEndpointAuthMethod.ClientSecretBasic, - null => null, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the client signing keys from the API model to the operator model. - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientSigningKey? FromApi(SigningKey? source) => source is null ? null : new() - { - Cert = source.Cert, - Key = source.Key, - Pkcs7 = source.Pkcs7, - }; - - /// - /// Transforms the client resource server association from the API model to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientResourceServerAssociation? FromApi(ClientResourceServerAssociation? source) => source is null ? null : new() - { - Identifier = source.Identifier, - Scopes = source.Scopes, - }; - - /// - /// Transforms the refresh token configuration from the API model to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientRefreshToken? FromApi(RefreshToken? source) => source is null ? null : new() - { - ExpirationType = FromApi(source.ExpirationType), - InfiniteIdleTokenLifetime = source.InfiniteIdleTokenLifetime, - InfiniteTokenLifetime = source.InfiniteTokenLifetime, - Leeway = source.Leeway, - RotationType = FromApi(source.RotationType), - TokenLifetime = source.TokenLifetime, - }; - - /// - /// Transforms the refresh token rotation type from the API model to the operator model. - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientRefreshTokenRotationType? FromApi(RefreshTokenRotationType? source) => source switch - { - RefreshTokenRotationType.Rotating => V1ClientRefreshTokenRotationType.Rotating, - RefreshTokenRotationType.NonRotating => V1ClientRefreshTokenRotationType.NonRotating, - null => null, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the refresh token expiration type from the API model to the operator model. - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientRefreshTokenExpirationType? FromApi(RefreshTokenExpirationType? source) => source switch - { - RefreshTokenExpirationType.Expiring => V1ClientRefreshTokenExpirationType.Expiring, - RefreshTokenExpirationType.NonExpiring => V1ClientRefreshTokenExpirationType.NonExpiring, - null => null, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the organization usage from the API model to the operator model. - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientOrganizationUsage? FromApi(OrganizationUsage? source) => source switch - { - OrganizationUsage.Deny => V1ClientOrganizationUsage.Deny, - OrganizationUsage.Allow => V1ClientOrganizationUsage.Allow, - OrganizationUsage.Require => V1ClientOrganizationUsage.Require, - null => null, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the organization require behavior from the API model to the operator model. - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientOrganizationRequireBehavior? FromApi(OrganizationRequireBehavior? source) => source switch - { - OrganizationRequireBehavior.NoPrompt => V1ClientOrganizationRequireBehavior.NoPrompt, - OrganizationRequireBehavior.PreLoginPrompt => V1ClientOrganizationRequireBehavior.PreLoginPrompt, - OrganizationRequireBehavior.PostLoginPrompt => V1ClientOrganizationRequireBehavior.PostLoginPrompt, - null => null, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the OIDC logout configuration from the API model to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientOidcLogoutConfig? FromApi(OidcLogoutConfig? source) => source is null ? null : new() - { - BackchannelLogoutUrls = source.BackchannelLogoutUrls, - BackchannelLogoutInitiators = FromApi(source.BackchannelLogoutInitiators), - }; - - /// - /// Transforms the backchannel logout initiators from the API model to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientBackchannelLogoutInitiators? FromApi(BackchannelLogoutInitiators? source) => source is null ? null : new() - { - Mode = FromApi(source.Mode), - SelectedInitiators = source.SelectedInitiators?.Select(FromApi).ToArray(), - }; - - /// - /// Transforms the logout initiators from the API model to the operator model. - /// - /// - /// - /// - internal static V1ClientLogoutInitiators FromApi(LogoutInitiators source) => source switch - { - LogoutInitiators.RpLogout => V1ClientLogoutInitiators.RpLogout, - LogoutInitiators.IdpLogout => V1ClientLogoutInitiators.IdpLogout, - LogoutInitiators.PasswordChanged => V1ClientLogoutInitiators.PasswordChanged, - LogoutInitiators.SessionExpired => V1ClientLogoutInitiators.SessionExpired, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the logout initiator modes from the API model to the operator model. - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientLogoutInitiatorModes? FromApi(LogoutInitiatorModes? source) => source switch - { - LogoutInitiatorModes.All => V1ClientLogoutInitiatorModes.All, - LogoutInitiatorModes.Custom => V1ClientLogoutInitiatorModes.Custom, - null => null, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the mobile configuration from the API model to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientMobile? FromApi(Mobile? source) => source is null ? null : new() - { - Android = FromApi(source.Android), - Ios = FromApi(source.Ios), - }; - - /// - /// Transforms the iOS mobile configuration from the API model to the operator model. - /// - /// - /// - internal static V1ClientMobile.MobileIos? FromApi(Mobile.MobileIos? source) - { - if (source is null) - return null; - if (source.AppBundleIdentifier is null && source.TeamId is null) - return null; - - return new() - { - AppBundleIdentifier = source.AppBundleIdentifier, - TeamId = source.TeamId, - }; - } - - /// - /// Transforms the Android mobile configuration from the API model to the operator model. - /// - /// - /// - internal static V1ClientMobile.MobileAndroid? FromApi(Mobile.MobileAndroid? source) - { - if (source is null) - return null; - if (source.AppPackageName is null && source.KeystoreHash is null) - return null; - - return new() - { - AppPackageName = source.AppPackageName, - KeystoreHash = source.KeystoreHash, - }; - } - - /// - /// Transforms the client JWT configuration from the API model to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientJwtConfiguration? FromApi(JwtConfiguration? source) => source is null ? null : new() - { - IsSecretEncoded = source.IsSecretEncoded, - LifetimeInSeconds = source.LifetimeInSeconds, - Scopes = FromApi(source.Scopes), - SigningAlgorithm = source.SigningAlgorithm, - }; - - /// - /// Transforms the client scopes from the API model to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientScopes? FromApi(Scopes? source) => source is null ? null : new() - { - Users = FromApi(source.Users), - UsersAppMetadata = FromApi(source.UsersAppMetadata), - Clients = FromApi(source.Clients), - ClientKeys = FromApi(source.ClientKeys), - Tokens = FromApi(source.Tokens), - Stats = FromApi(source.Stats), - }; - - /// - /// Transforms the client scope entry from the API model to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientScopeEntry? FromApi(ScopeEntry? source) => source is null ? null : new() - { - Actions = source.Actions, - }; - - /// - /// Transforms the client encryption key configuration from the API model to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientEncryptionKey? FromApi(EncryptionKey? source) => source is null ? null : new() - { - Certificate = source.Certificate, - PublicKey = source.PublicKey, - Subject = source.Subject, - }; - - /// - /// Extracts the default organization configuration from the API response and transforms it to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientDefaultOrganization? FromApi(DefaultOrganization? source) => source is null ? null : new() - { - OrganizationId = source.OrganizationId, - Flows = source.Flows?.Select(FromApi).ToArray(), - }; - - /// - /// Transforms the client flow from the API model to the operator model. - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientFlows FromApi(Flows source) => source switch - { - Flows.ClientCredentials => V1ClientFlows.ClientCredentials, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the compliance level from the API model to the operator model. - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientComplianceLevel? FromApi(ComplianceLevel? source) => source switch - { - ComplianceLevel.NONE => V1ClientComplianceLevel.NONE, - ComplianceLevel.FAPI1_ADV_PKJ_PAR => V1ClientComplianceLevel.FAPI1_ADV_PKJ_PAR, - ComplianceLevel.FAPI1_ADV_MTLS_PAR => V1ClientComplianceLevel.FAPI1_ADV_MTLS_PAR, - null => null, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the application type from the API model to the operator model. - /// - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientApplicationType? FromApi(ClientApplicationType? source) => source switch - { - ClientApplicationType.Box => V1ClientApplicationType.Box, - ClientApplicationType.Cloudbees => V1ClientApplicationType.Cloudbees, - ClientApplicationType.Concur => V1ClientApplicationType.Concur, - ClientApplicationType.Dropbox => V1ClientApplicationType.Dropbox, - ClientApplicationType.Echosign => V1ClientApplicationType.Echosign, - ClientApplicationType.Egnyte => V1ClientApplicationType.Egnyte, - ClientApplicationType.MsCrm => V1ClientApplicationType.MsCrm, - ClientApplicationType.Native => V1ClientApplicationType.Native, - ClientApplicationType.NewRelic => V1ClientApplicationType.NewRelic, - ClientApplicationType.NonInteractive => V1ClientApplicationType.NonInteractive, - ClientApplicationType.Office365 => V1ClientApplicationType.Office365, - ClientApplicationType.RegularWeb => V1ClientApplicationType.RegularWeb, - ClientApplicationType.Rms => V1ClientApplicationType.Rms, - ClientApplicationType.Salesforce => V1ClientApplicationType.Salesforce, - ClientApplicationType.Sentry => V1ClientApplicationType.Sentry, - ClientApplicationType.SharePoint => V1ClientApplicationType.SharePoint, - ClientApplicationType.Slack => V1ClientApplicationType.Slack, - ClientApplicationType.SpringCm => V1ClientApplicationType.SpringCm, - ClientApplicationType.Spa => V1ClientApplicationType.Spa, - ClientApplicationType.Zendesk => V1ClientApplicationType.Zendesk, - ClientApplicationType.Zoom => V1ClientApplicationType.Zoom, - ClientApplicationType.ResourceServer => V1ClientApplicationType.ResourceServer, - ClientApplicationType.ExpressConfiguration => V1ClientApplicationType.ExpressConfiguration, - ClientApplicationType.SsoIntegration => V1ClientApplicationType.SsoIntegration, - ClientApplicationType.Oag => V1ClientApplicationType.Oag, - null => null, - _ => throw new NotImplementedException(), - }; - - /// - /// Extracts the add-ons configuration from the API response and transforms it to the operator model. - /// - /// - /// - [return: NotNullIfNotNull(nameof(source))] - internal static V1ClientAddons? FromApi(Addons? source) => source is { } addOns ? new V1ClientAddons() - { - Aws = FromApiAddonAws(addOns.AmazonWebServices as JObject), - AzureSb = FromApiAddonAzureSb(addOns.AzureServiceBus as JObject), - Box = FromApiAddonDictionary(addOns.Box as JObject), - Cloudbees = FromApiAddonDictionary(addOns.CloudBees as JObject), - Concur = FromApiAddonDictionary(addOns.Concur as JObject), - Dropbox = FromApiAddonDictionary(addOns.DropBox as JObject), - Echosign = FromApiAddonEchoSign(addOns.EchoSign as JObject), - Egnyte = FromApiAddonEgnyte(addOns.Egnyte as JObject), - Firebase = FromApiAddonFirebase(addOns.FireBase as JObject), - Newrelic = FromApiAddonNewRelic(addOns.NewRelic as JObject), - Office365 = FromApiAddonOffice365(addOns.Office365 as JObject), - Salesforce = FromApiAddonSalesforce(addOns.SalesForce as JObject), - SalesforceApi = FromApiAddonSalesforceApi(addOns.SalesForceApi as JObject), - SalesforceSandboxApi = FromApiAddonSalesforceSandboxApi(addOns.SalesForceSandboxApi as JObject), - Samlp = FromApiAddonSaml(addOns.SamlP as JObject), - SapApi = FromApiAddonSapApi(addOns.SapApi as JObject), - Sharepoint = FromApiAddonSharePoint(addOns.SharePoint as JObject), - Springcm = FromApiAddonSpringCm(addOns.SpringCM as JObject), - Wsfed = FromApiAddonDictionary(addOns.WsFed as JObject), - Zendesk = FromApiAddonZendesk(addOns.Zendesk as JObject), - Zoom = FromApiAddonZoom(addOns.Zoom as JObject), - } : null; - - internal static V1ClientAddonAws? FromApiAddonAws(JObject? o) => o is null ? null : new() - { - Principal = (string?)o["principal"], - Role = (string?)o["role"], - LifetimeInSeconds = (int?)o["lifetime_in_seconds"], - }; - - internal static V1ClientAddonAzureSb? FromApiAddonAzureSb(JObject? o) => o is null ? null : new() - { - Namespace = (string?)o["namespace"], - SasKeyName = (string?)o["sasKeyName"], - SasKey = (string?)o["sasKey"], - EntityPath = (string?)o["entityPath"], - }; - - internal static Dictionary? FromApiAddonDictionary(JObject? o) - { - return o?.ToObject>(); - } - - internal static V1ClientAddonEchoSign? FromApiAddonEchoSign(JObject? o) => o is null ? null : new() - { - Domain = (string?)o["domain"], - }; - - internal static V1ClientAddonEgnyte? FromApiAddonEgnyte(JObject? o) => o is null ? null : new() - { - Domain = (string?)o["domain"], - }; - - internal static V1ClientAddonFirebase? FromApiAddonFirebase(JObject? o) => o is null ? null : new() - { - Secret = (string?)o["secret"], - PrivateKeyId = (string?)o["private_key_id"], - PrivateKey = (string?)o["private_key"], - ClientEmail = (string?)o["client_email"], - LifetimeInSeconds = (int?)o["lifetime_in_seconds"], - }; - - internal static V1ClientAddonNewRelic? FromApiAddonNewRelic(JObject? o) => o is null ? null : new() - { - Account = (string?)o["account"], - }; - - internal static V1ClientAddonOffice365? FromApiAddonOffice365(JObject? o) => o is null ? null : new() - { - Domain = (string?)o["domain"], - Connection = (string?)o["connection"], - }; - - internal static V1ClientAddonSalesforce? FromApiAddonSalesforce(JObject? o) => o is null ? null : new() - { - EntityId = (string?)o["entity_id"], - }; - - internal static V1ClientAddonSalesforceApi? FromApiAddonSalesforceApi(JObject? o) => o is null ? null : new() - { - Clientid = (string?)o["clientid"], - Principal = (string?)o["principal"], - CommunityName = (string?)o["communityName"], - CommunityUrlSection = (string?)o["community_url_section"], - }; - - internal static V1ClientAddonSalesforceSandboxApi? FromApiAddonSalesforceSandboxApi(JObject? o) => o is null ? null : new() - { - Clientid = (string?)o["clientid"], - Principal = (string?)o["principal"], - CommunityName = (string?)o["communityName"], - CommunityUrlSection = (string?)o["community_url_section"], - }; - - internal static V1ClientAddonSaml? FromApiAddonSaml(JObject? o) => o is null ? null : new() - { - Mappings = o["mappings"]?.ToObject>(), - Audience = (string?)o["audience"], - Recipient = (string?)o["recipient"], - CreateUpnClaim = (bool?)o["createUpnClaim"], - MapUnknownClaimsAsIs = (bool?)o["mapUnknownClaimsAsIs"], - PassthroughClaimsWithNoMapping = (bool?)o["passthroughClaimsWithNoMapping"], - MapIdentities = (bool?)o["mapIdentities"], - SignatureAlgorithm = (string?)o["signatureAlgorithm"], - DigestAlgorithm = (string?)o["digestAlgorithm"], - Issuer = (string?)o["issuer"], - Destination = (string?)o["destination"], - LifetimeInSeconds = (int?)o["lifetimeInSeconds"], - SignResponse = (bool?)o["signResponse"], - NameIdentifierFormat = (string?)o["nameIdentifierFormat"], - NameIdentifierProbes = o["nameIdentifierProbes"]?.ToObject>(), - AuthnContextClassRef = (string?)o["authnContextClassRef"], - }; - - internal static V1ClientAddonSapapi? FromApiAddonSapApi(JObject? o) => o is null ? null : new() - { - Clientid = (string?)o["clientid"], - UsernameAttribute = (string?)o["usernameAttribute"], - TokenEndpointUrl = (string?)o["tokenEndpointUrl"], - Scope = (string?)o["scope"], - ServicePassword = (string?)o["servicePassword"], - NameIdentifierFormat = (string?)o["nameIdentifierFormat"], - }; - - internal static V1ClientAddonSharePoint? FromApiAddonSharePoint(JObject? o) => o is null ? null : new() - { - Url = (string?)o["url"], - ExternalUrl = (o["external_url"] as JObject)?.ToObject(), - }; - - internal static V1ClientAddonSpringCm? FromApiAddonSpringCm(JObject? o) => o is null ? null : new() - { - Acsurl = (string?)o["acsurl"], - }; - - internal static V1ClientAddonZendesk? FromApiAddonZendesk(JObject? o) => o is null ? null : new() - { - AccountName = (string?)o["accountName"], - }; - - internal static V1ClientAddonZoom? FromApiAddonZoom(JObject? o) => o is null ? null : new() - { - Account = (string?)o["account"], - }; - - /// - /// Applies the add-ons configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientAddons source, Addons target) - { - if (source.Aws is { } aws) - target.AmazonWebServices = aws; - - if (source.AzureSb is { } azure_sb) - target.AzureServiceBus = azure_sb; - - if (source.Box is { } box) - target.Box = box; - - if (source.Cloudbees is { } cloudbees) - target.CloudBees = cloudbees; - - if (source.Concur is { } concur) - target.Concur = concur; - - if (source.Dropbox is { } dropbox) - target.DropBox = dropbox; - - if (source.Echosign is { } echosign) - target.EchoSign = echosign; - - if (source.Egnyte is { } egnyte) - target.Egnyte = egnyte; - - if (source.Firebase is { } firebase) - target.FireBase = firebase; - - if (source.Newrelic is { } newrelic) - target.NewRelic = newrelic; - - if (source.Office365 is { } office365) - target.Office365 = office365; - - if (source.Salesforce is { } salesforce) - target.SalesForce = salesforce; - - if (source.SalesforceApi is { } salesforce_api) - target.SalesForceApi = salesforce_api; - - if (source.SalesforceSandboxApi is { } salesforce_sandbox_api) - target.SalesForceSandboxApi = salesforce_sandbox_api; - - if (source.Samlp is { } samlp) - target.SamlP = samlp; - - if (source.SapApi is { } sap_api) - target.SapApi = sap_api; - - if (source.Sharepoint is { } sharepoint) - target.SharePoint = sharepoint; - - if (source.Springcm is { } springcm) - target.SpringCM = springcm; - - if (source.Wsfed is { } wsfed) - target.WsFed = wsfed; - - if (source.Zendesk is { } zendesk) - target.Zendesk = zendesk; - - if (source.Zoom is { } zoom) - target.Zoom = zoom; - } - - /// - /// Applies the encryption key configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientEncryptionKey source, EncryptionKey target) - { - if (source.Certificate is { } cert) - target.Certificate = cert; - - if (source.PublicKey is { } pub) - target.PublicKey = pub; - - if (source.Subject is { } subject) - target.Subject = subject; - } - - /// - /// Applies the scope entry configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientScopeEntry source, ScopeEntry target) - { - if (source.Actions is { } actions) - target.Actions = actions; - } - - /// - /// Applies the scopes configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientScopes source, Scopes target) - { - if (source.Users is { } users) - ApplyToApi(users, target.Users ??= new ScopeEntry()); - - if (source.UsersAppMetadata is { } users_app_metadata) - ApplyToApi(users_app_metadata, target.UsersAppMetadata ??= new ScopeEntry()); - - if (source.Clients is { } clients) - ApplyToApi(clients, target.Clients ??= new ScopeEntry()); - - if (source.ClientKeys is { } client_keys) - ApplyToApi(client_keys, target.ClientKeys ??= new ScopeEntry()); - - if (source.Tokens is { } tokens) - ApplyToApi(tokens, target.Tokens ??= new ScopeEntry()); - - if (source.Stats is { } stats) - ApplyToApi(stats, target.Stats ??= new ScopeEntry()); - } - - /// - /// Applies the JWT configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientJwtConfiguration source, JwtConfiguration target) - { - if (source.IsSecretEncoded is { } secret_encoded) - target.IsSecretEncoded = secret_encoded; - - if (source.LifetimeInSeconds is { } lifetime_in_seconds) - target.LifetimeInSeconds = lifetime_in_seconds; - - if (source.Scopes is { } scopes) - ApplyToApi(scopes, target.Scopes ??= new Scopes()); - - if (source.SigningAlgorithm is { } alg) - target.SigningAlgorithm = alg; - } - - /// - /// Applies the mobile configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientMobile.MobileAndroid source, Mobile.MobileAndroid target) - { - if (source.AppPackageName is { } app_package_name) - target.AppPackageName = app_package_name; - - if (source.KeystoreHash is { } keystore_hash) - target.KeystoreHash = keystore_hash; - } - - /// - /// Applies the iOS mobile configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientMobile.MobileIos source, Mobile.MobileIos target) - { - if (source.AppBundleIdentifier is { } app_bundle_identifier) - target.AppBundleIdentifier = app_bundle_identifier; - - if (source.TeamId is { } team_id) - target.TeamId = team_id; - } - - /// - /// Applies the mobile configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientMobile source, Mobile target) - { - if (source.Android is { } android) - if (source.Android.AppPackageName is not null || source.Android.KeystoreHash is not null) - ApplyToApi(android, target.Android ??= new Mobile.MobileAndroid()); - - if (source.Ios is { } ios) - if (source.Ios.AppBundleIdentifier is not null || source.Ios.TeamId is not null) - ApplyToApi(ios, target.Ios ??= new Mobile.MobileIos()); - } - - /// - /// Transforms the compliance level from the operator model to the API model. - /// - /// - /// - /// - internal static ComplianceLevel ToApi(V1ClientComplianceLevel source) => source switch - { - V1ClientComplianceLevel.NONE => ComplianceLevel.NONE, - V1ClientComplianceLevel.FAPI1_ADV_PKJ_PAR => ComplianceLevel.FAPI1_ADV_PKJ_PAR, - V1ClientComplianceLevel.FAPI1_ADV_MTLS_PAR => ComplianceLevel.FAPI1_ADV_MTLS_PAR, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the organization require behavior from the operator model to the API model. - /// - /// - /// - /// - internal static OrganizationRequireBehavior ToApi(V1ClientOrganizationRequireBehavior source) => source switch - { - V1ClientOrganizationRequireBehavior.NoPrompt => OrganizationRequireBehavior.NoPrompt, - V1ClientOrganizationRequireBehavior.PreLoginPrompt => OrganizationRequireBehavior.PreLoginPrompt, - V1ClientOrganizationRequireBehavior.PostLoginPrompt => OrganizationRequireBehavior.PostLoginPrompt, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the organization usage from the operator model to the API model. - /// - /// - /// - /// - internal static OrganizationUsage ToApi(V1ClientOrganizationUsage source) => source switch - { - V1ClientOrganizationUsage.Deny => OrganizationUsage.Deny, - V1ClientOrganizationUsage.Allow => OrganizationUsage.Allow, - V1ClientOrganizationUsage.Require => OrganizationUsage.Require, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the refresh token rotation type from the operator model to the API model. - /// - /// - /// - /// - internal static RefreshTokenRotationType ToApi(V1ClientRefreshTokenRotationType source) => source switch - { - V1ClientRefreshTokenRotationType.Rotating => RefreshTokenRotationType.Rotating, - V1ClientRefreshTokenRotationType.NonRotating => RefreshTokenRotationType.NonRotating, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the refresh token expiration type from the operator model to the API model. - /// - /// - /// - /// - internal static RefreshTokenExpirationType ToApi(V1ClientRefreshTokenExpirationType source) => source switch - { - V1ClientRefreshTokenExpirationType.Expiring => RefreshTokenExpirationType.Expiring, - V1ClientRefreshTokenExpirationType.NonExpiring => RefreshTokenExpirationType.NonExpiring, - _ => throw new NotImplementedException(), - }; - - /// - /// Applies the refresh token configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientRefreshToken source, RefreshToken target) - { - if (source.RotationType is { } rotation_type) - target.RotationType = ToApi(rotation_type); - - if (source.ExpirationType is { } expiration_type) - target.ExpirationType = ToApi(expiration_type); - - if (source.Leeway is { } leeway) - target.Leeway = leeway; - - if (source.TokenLifetime is { } token_lifetime) - target.TokenLifetime = token_lifetime; - - if (source.InfiniteTokenLifetime is { } infinite_token_lifetime) - target.InfiniteTokenLifetime = infinite_token_lifetime; - - if (source.IdleTokenLifetime is { } idle_token_lifetime) - target.IdleTokenLifetime = idle_token_lifetime; - - if (source.InfiniteIdleTokenLifetime is { } infinite_idle_token_lifetime) - target.InfiniteIdleTokenLifetime = infinite_idle_token_lifetime; - } - - /// - /// Transforms the logout initiator modes from the operator model to the API model. - /// - /// - /// - /// - internal static LogoutInitiatorModes ToApi(V1ClientLogoutInitiatorModes source) - { - return source switch - { - V1ClientLogoutInitiatorModes.All => LogoutInitiatorModes.All, - V1ClientLogoutInitiatorModes.Custom => LogoutInitiatorModes.Custom, - _ => throw new NotImplementedException(), - }; - } - - /// - /// Transforms the logout initiators from the operator model to the API model. - /// - /// - /// - /// - internal static LogoutInitiators ToApi(V1ClientLogoutInitiators source) => source switch - { - V1ClientLogoutInitiators.RpLogout => LogoutInitiators.RpLogout, - V1ClientLogoutInitiators.IdpLogout => LogoutInitiators.IdpLogout, - V1ClientLogoutInitiators.PasswordChanged => LogoutInitiators.PasswordChanged, - V1ClientLogoutInitiators.SessionExpired => LogoutInitiators.SessionExpired, - _ => throw new NotImplementedException(), - }; - - /// - /// Applies the backchannel logout initiators configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientBackchannelLogoutInitiators source, BackchannelLogoutInitiators target) - { - if (source.Mode is { } backchannel_logout_urls) - target.Mode = ToApi(backchannel_logout_urls); - - if (source.SelectedInitiators is { } backchannel_logout_initiators) - target.SelectedInitiators = [.. backchannel_logout_initiators.Select(ToApi)]; - } - - /// - /// Applies the OIDC logout configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientOidcLogoutConfig source, OidcLogoutConfig target) - { - if (source.BackchannelLogoutUrls is { } backchannel_logout_urls) - target.BackchannelLogoutUrls = backchannel_logout_urls; - - if (source.BackchannelLogoutInitiators is { } backchannel_logout_initiators) - ApplyToApi(backchannel_logout_initiators, target.BackchannelLogoutInitiators ??= new()); - } - - /// - /// Applies the configuration to the API request. - /// - /// - /// - internal static void ApplyToApi(V1ClientConf conf, ClientBase request) - { - if (conf.AddOns is { } addons) - ApplyToApi(addons, request.AddOns ??= new()); - - if (conf.AllowedClients is not null) - request.AllowedClients = conf.AllowedClients; - - if (conf.AllowedLogoutUrls is not null) - request.AllowedLogoutUrls = conf.AllowedLogoutUrls; - - if (conf.AllowedOrigins is not null) - request.AllowedOrigins = conf.AllowedOrigins; - - if (conf.WebOrigins is not null) - request.WebOrigins = conf.WebOrigins; - - if (conf.InitiateLoginUri is not null) - request.InitiateLoginUri = conf.InitiateLoginUri; - - if (conf.Callbacks is not null) - request.Callbacks = conf.Callbacks; - - if (conf.ClientAliases is not null) - request.ClientAliases = conf.ClientAliases; - - if (conf.ClientMetaData is not null) - request.ClientMetaData = conf.ClientMetaData; - - if (conf.IsCustomLoginPageOn is not null) - request.IsCustomLoginPageOn = conf.IsCustomLoginPageOn; - - if (conf.IsFirstParty is not null) - request.IsFirstParty = conf.IsFirstParty; - - if (conf.CustomLoginPage is not null) - request.CustomLoginPage = conf.CustomLoginPage; - - if (conf.CustomLoginPagePreview is not null) - request.CustomLoginPagePreview = conf.CustomLoginPagePreview; - - if (conf.EncryptionKey is { } encryption_key) - ApplyToApi(encryption_key, request.EncryptionKey ??= new()); - - if (conf.FormTemplate is not null) - request.FormTemplate = conf.FormTemplate; - - if (conf.GrantTypes is not null) - request.GrantTypes = conf.GrantTypes.Distinct().ToArray(); - - if (conf.JwtConfiguration is { } jwt_configuration) - ApplyToApi(jwt_configuration, request.JwtConfiguration ??= new()); - - if (conf.Mobile is { } mobile) - { - var target = new Mobile(); - ApplyToApi(mobile, target); - - // only set on request if at least one of the mobile configurations is set, as the API will reject an empty mobile object - if (target.Android is not null || target.Ios is not null) - request.Mobile = target; - } - - if (conf.Name is not null) - request.Name = conf.Name; - - if (conf.Description is not null) - request.Description = conf.Description; - - if (conf.LogoUri is not null) - request.LogoUri = conf.LogoUri; - - if (conf.OidcConformant is not null) - request.OidcConformant = conf.OidcConformant; - - if (conf.OidcLogout is { } oidc_logout) - ApplyToApi(oidc_logout, request.OidcLogout ??= new()); - - if (conf.Sso is not null) - request.Sso = conf.Sso; - - if (conf.RefreshToken is { } refresh_token) - ApplyToApi(refresh_token, request.RefreshToken ??= new()); - - if (conf.OrganizationUsage is { } organization_usage) - request.OrganizationUsage = ToApi(organization_usage); - - if (conf.OrganizationRequireBehavior is { } organization_require_behavior) - request.OrganizationRequireBehavior = ToApi(organization_require_behavior); - - if (conf.CrossOriginAuthentication is not null) - request.CrossOriginAuthentication = conf.CrossOriginAuthentication; - - if (conf.RequirePushedAuthorizationRequests is not null) - request.RequirePushedAuthorizationRequests = conf.RequirePushedAuthorizationRequests; - - if (conf.ComplianceLevel is { } compliance_level) - request.ComplianceLevel = ToApi(compliance_level); - - if (conf.RequireProofOfPossession is not null) - request.RequireProofOfPossession = conf.RequireProofOfPossession; - } - - /// - /// Transforms the application type from the operator model to the API model. - /// - /// - /// - /// - internal static ClientApplicationType ToApi(V1ClientApplicationType source) => source switch - { - V1ClientApplicationType.Box => ClientApplicationType.Box, - V1ClientApplicationType.Cloudbees => ClientApplicationType.Cloudbees, - V1ClientApplicationType.Concur => ClientApplicationType.Concur, - V1ClientApplicationType.Dropbox => ClientApplicationType.Dropbox, - V1ClientApplicationType.Echosign => ClientApplicationType.Echosign, - V1ClientApplicationType.Egnyte => ClientApplicationType.Egnyte, - V1ClientApplicationType.MsCrm => ClientApplicationType.MsCrm, - V1ClientApplicationType.Native => ClientApplicationType.Native, - V1ClientApplicationType.NewRelic => ClientApplicationType.NewRelic, - V1ClientApplicationType.NonInteractive => ClientApplicationType.NonInteractive, - V1ClientApplicationType.Office365 => ClientApplicationType.Office365, - V1ClientApplicationType.RegularWeb => ClientApplicationType.RegularWeb, - V1ClientApplicationType.Rms => ClientApplicationType.Rms, - V1ClientApplicationType.Salesforce => ClientApplicationType.Salesforce, - V1ClientApplicationType.Sentry => ClientApplicationType.Sentry, - V1ClientApplicationType.SharePoint => ClientApplicationType.SharePoint, - V1ClientApplicationType.Slack => ClientApplicationType.Slack, - V1ClientApplicationType.SpringCm => ClientApplicationType.SpringCm, - V1ClientApplicationType.Spa => ClientApplicationType.Spa, - V1ClientApplicationType.Zendesk => ClientApplicationType.Zendesk, - V1ClientApplicationType.Zoom => ClientApplicationType.Zoom, - _ => throw new NotImplementedException(), - }; - - /// - /// Transforms the token endpoint authentication method from the operator model to the API model. - /// - /// - /// - /// - internal static TokenEndpointAuthMethod ToApi(V1ClientTokenEndpointAuthMethod source) => source switch - { - V1ClientTokenEndpointAuthMethod.None => TokenEndpointAuthMethod.None, - V1ClientTokenEndpointAuthMethod.ClientSecretPost => TokenEndpointAuthMethod.ClientSecretPost, - V1ClientTokenEndpointAuthMethod.ClientSecretBasic => TokenEndpointAuthMethod.ClientSecretBasic, - _ => throw new NotImplementedException(), - }; - - /// - /// Applies client configuration settings to the specified API client creation request. - /// - /// - /// - internal static void ApplyToApi(V1ClientConf conf, ClientCreateRequest request) - { - if (conf.ApplicationType is { } app_type) - request.ApplicationType = ToApi(app_type); - - if (conf.TokenEndpointAuthMethod is { } token_endpoint_auth_method) - request.TokenEndpointAuthMethod = ToApi(token_endpoint_auth_method); - - ApplyToApi(conf, (ClientBase)request); - } - - /// - /// Applies the specified client configuration to the API update request. - /// - /// - /// - internal static void ApplyToApi(V1ClientConf conf, ClientUpdateRequest request) - { - if (conf.ApplicationType is { } app_type) - request.ApplicationType = ToApi(app_type); - - if (conf.TokenEndpointAuthMethod is { } token_endpoint_auth_method) - request.TokenEndpointAuthMethod = ToApi(token_endpoint_auth_method); - - ApplyToApi(conf, (ClientBase)request); - } - - /// - /// Initializes a new instance. - /// - /// - /// - /// - /// - public V1ClientController(IKubernetesClient kube, IMemoryCache cache, IOptions options, ILogger logger) : - base(kube, cache, options, logger) - { - - } - - /// - protected override string EntityTypeName => "Client"; - - /// - protected override async Task Get(IManagementApiClient api, string id, string defaultNamespace, CancellationToken cancellationToken) - { - try - { - return FromApi(await api.Clients.GetAsync(id, cancellationToken: cancellationToken)); - } - catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) - { - return null; - } - } - - /// - protected override async Task Find(IManagementApiClient api, V1Client entity, V1Client.SpecDef spec, string defaultNamespace, CancellationToken cancellationToken) - { - if (spec.Find is not null) - { - // attempt to search by client ID - if (spec.Find.ClientId is string clientId) - { - try - { - var client = await api.Clients.GetAsync(clientId, "client_id,name", cancellationToken: cancellationToken); - Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} found existing client: {Name}", EntityTypeName, entity.Namespace(), entity.Name(), client.Name); - return client.ClientId; - } - catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) - { - Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} could not find client with id {ClientId}.", EntityTypeName, entity.Namespace(), entity.Name(), clientId); - } - } - - // attempt to search by name - if (spec.Find.Name is string name) - { - var list = await api.Clients.GetAllAsync(new GetClientsRequest() { Fields = "client_id,name" }, cancellationToken: cancellationToken); - var self = list.FirstOrDefault(i => i.Name == name); - return self?.ClientId; - } - } - else - { - var conf = spec.Init ?? spec.Conf; - if (conf is { Name: string name }) - { - var list = await api.Clients.GetAllAsync(new GetClientsRequest() { Fields = "client_id,name" }, cancellationToken: cancellationToken); - var self = list.FirstOrDefault(i => i.Name == name); - return self?.ClientId; - } - } - - return null; - } - - /// - protected override string? ValidateCreate(V1ClientConf conf) - { - if (conf.ApplicationType == null) - return "missing a value for application type"; - - return null; - } - - /// - protected override async Task Create(IManagementApiClient api, V1ClientConf conf, string defaultNamespace, CancellationToken cancellationToken) - { - Logger.LogInformation("{EntityTypeName} creating client in Auth0 with name: {ClientName}", EntityTypeName, conf.Name); - - // transform request - var req = new ClientCreateRequest(); - ApplyToApi(conf, req); - - var self = await api.Clients.CreateAsync(req, cancellationToken); - Logger.LogInformation("{EntityTypeName} successfully created client in Auth0 with ID: {ClientId} and name: {ClientName}", EntityTypeName, self.ClientId, conf.Name); - return self.ClientId; - } - - /// - protected override async Task Update(IManagementApiClient api, string id, V1ClientConf? last, V1ClientConf conf, string defaultNamespace, CancellationToken cancellationToken) - { - Logger.LogInformation("{EntityTypeName} updating client in Auth0 with id: {ClientId} and name: {ClientName}", EntityTypeName, id, conf.Name); - - // transform request - var req = new ClientUpdateRequest(); - ApplyToApi(conf, req); - - // explicitely null out missing metadata if previously present - if (last is not null && last.ClientMetaData != null && conf.ClientMetaData != null) - foreach (string key in last.ClientMetaData.Keys) - if (conf.ClientMetaData.ContainsKey(key) == false) - req.ClientMetaData[key] = null; - - await api.Clients.UpdateAsync(id, req, cancellationToken); - Logger.LogInformation("{EntityTypeName} successfully updated client in Auth0 with id: {ClientId} and name: {ClientName}", EntityTypeName, id, conf.Name); - } - - /// - protected override async Task ApplyStatus(IManagementApiClient api, V1Client entity, V1ClientConf lastConf, string defaultNamespace, CancellationToken cancellationToken) - { - // Always attempt to apply secret if secretRef is specified, regardless of whether we have the clientSecret value - // This ensures secret resources are created for existing clients even when Auth0 API doesn't return the secret - if (entity.Spec.SecretRef is not null && entity.Status.Id is not null) - { - var client = await api.Clients.GetAsync(entity.Status.Id, "client_id,client_secret", cancellationToken: cancellationToken); - await ApplySecret(entity, client.ClientId, client.ClientSecret, defaultNamespace, cancellationToken); - } - - await base.ApplyStatus(api, entity, lastConf, defaultNamespace, cancellationToken); - } - - /// - /// Applies the client secret. - /// - /// - /// - /// - /// - /// - /// - async Task ApplySecret(V1Client entity, string? clientId, string? clientSecret, string defaultNamespace, CancellationToken cancellationToken) - { - if (entity.Spec.SecretRef is null) - return; - - // find existing secret or create - var secret = await ResolveSecretRef(entity.Spec.SecretRef, entity.Spec.SecretRef.NamespaceProperty ?? defaultNamespace, cancellationToken); - if (secret is null) - { - Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} referenced secret {SecretName} which does not exist: creating.", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); - secret = await Kube.CreateAsync( - new V1Secret() { Metadata = new V1ObjectMeta() { NamespaceProperty = entity.Spec.SecretRef.NamespaceProperty ?? defaultNamespace, Name = entity.Spec.SecretRef.Name } } - .WithOwnerReference(entity), - cancellationToken); - } - - // only apply actual values if we are the owner - if (secret.IsOwnedBy(entity)) - { - Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} referenced secret {SecretName}: updating.", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); - secret.StringData ??= new Dictionary(); - - // Always set clientId if available - if (clientId is not null) - { - secret.StringData["clientId"] = clientId; - Logger.LogDebug("{EntityTypeName} {EntityNamespace}/{EntityName} updated secret {SecretName} with clientId", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); - } - else if (!secret.StringData.ContainsKey("clientId")) - { - // Initialize empty clientId field if not present and no value available - secret.StringData["clientId"] = ""; - Logger.LogDebug("{EntityTypeName} {EntityNamespace}/{EntityName} initialized empty clientId in secret {SecretName}", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); - } - - // Handle clientSecret - for existing clients, Auth0 API doesn't return the secret - if (clientSecret is not null) - { - secret.StringData["clientSecret"] = clientSecret; - Logger.LogDebug("{EntityTypeName} {EntityNamespace}/{EntityName} updated secret {SecretName} with clientSecret", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); - } - else if (!secret.StringData.ContainsKey("clientSecret")) - { - // Initialize empty clientSecret field if not present and no value available - // Note: For existing clients, Auth0 API doesn't return the secret value for security reasons - secret.StringData["clientSecret"] = ""; - Logger.LogDebug("{EntityTypeName} {EntityNamespace}/{EntityName} initialized empty clientSecret in secret {SecretName} (Auth0 API does not return secrets for existing clients)", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); - } - - secret = await Kube.UpdateAsync(secret, cancellationToken); - Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} successfully updated secret {SecretName}", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); - } - else - { - Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} secret {SecretName} exists but is not owned by this client, skipping update", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); - } - } - - /// - protected override async Task DeletedAsync(IManagementApiClient api, string id, CancellationToken cancellationToken) - { - Logger.LogInformation("{EntityTypeName} deleting client from Auth0 with ID: {ClientId} (reason: Kubernetes entity deleted)", EntityTypeName, id); - await api.Clients.DeleteAsync(id, cancellationToken); - Logger.LogInformation("{EntityTypeName} successfully deleted client from Auth0 with ID: {ClientId}", EntityTypeName, id); - } - - } - -} diff --git a/src/Alethic.Auth0.Operator/Controllers/V1ClientGrantController.cs b/src/Alethic.Auth0.Operator/Controllers/V1ClientGrantController.cs index a824c6b..67df7cf 100644 --- a/src/Alethic.Auth0.Operator/Controllers/V1ClientGrantController.cs +++ b/src/Alethic.Auth0.Operator/Controllers/V1ClientGrantController.cs @@ -8,7 +8,7 @@ using Alethic.Auth0.Operator.Options; using Auth0.ManagementApi; -using Auth0.ManagementApi.Models; +using Auth0.ManagementApi.ClientGrants; using k8s.Models; @@ -47,23 +47,35 @@ public V1ClientGrantController(IKubernetesClient kube, IMemoryCache cache, IOpti } /// - /// Converts from an API to a local . + /// Converts from an API to a local . /// - internal static V1ClientGrantOrganizationUsage? FromApi(OrganizationUsage? source) => source switch + internal static V1ClientGrantOrganizationUsage? FromApi(ClientGrantOrganizationNullableUsageEnum? source) => source?.Value switch { - OrganizationUsage.Deny => V1ClientGrantOrganizationUsage.Deny, - OrganizationUsage.Allow => V1ClientGrantOrganizationUsage.Allow, - OrganizationUsage.Require => V1ClientGrantOrganizationUsage.Require, + ClientGrantOrganizationNullableUsageEnum.Values.Deny => V1ClientGrantOrganizationUsage.Deny, + ClientGrantOrganizationNullableUsageEnum.Values.Allow => V1ClientGrantOrganizationUsage.Allow, + ClientGrantOrganizationNullableUsageEnum.Values.Require => V1ClientGrantOrganizationUsage.Require, null => null, _ => throw new InvalidOperationException(), }; /// - /// Converts relevant fields from a API response to a . + /// Converts from an API to a local . + /// + internal static V1ClientGrantOrganizationUsage? FromApi(ClientGrantOrganizationUsageEnum? source) => source?.Value switch + { + ClientGrantOrganizationUsageEnum.Values.Deny => V1ClientGrantOrganizationUsage.Deny, + ClientGrantOrganizationUsageEnum.Values.Allow => V1ClientGrantOrganizationUsage.Allow, + ClientGrantOrganizationUsageEnum.Values.Require => V1ClientGrantOrganizationUsage.Require, + null => null, + _ => throw new InvalidOperationException(), + }; + + /// + /// Converts relevant fields from a API response to a . /// Note: and cannot be /// populated from the API response and are left null. /// - internal static V1ClientGrantConf? FromApi(ClientGrant? source) + internal static V1ClientGrantConf? FromApi(GetClientGrantResponseContent? source) { if (source is null) return null; @@ -77,35 +89,48 @@ public V1ClientGrantController(IKubernetesClient kube, IMemoryCache cache, IOpti } /// - /// Converts from a local to an API . + /// Converts from a local to an API . /// - internal static OrganizationUsage? ToApi(V1ClientGrantOrganizationUsage? source) => source switch + internal static ClientGrantOrganizationUsageEnum? ToApi(V1ClientGrantOrganizationUsage? source) => source switch { - V1ClientGrantOrganizationUsage.Deny => OrganizationUsage.Deny, - V1ClientGrantOrganizationUsage.Allow => OrganizationUsage.Allow, - V1ClientGrantOrganizationUsage.Require => OrganizationUsage.Require, + V1ClientGrantOrganizationUsage.Deny => new ClientGrantOrganizationUsageEnum(ClientGrantOrganizationUsageEnum.Values.Deny), + V1ClientGrantOrganizationUsage.Allow => new ClientGrantOrganizationUsageEnum(ClientGrantOrganizationUsageEnum.Values.Allow), + V1ClientGrantOrganizationUsage.Require => new ClientGrantOrganizationUsageEnum(ClientGrantOrganizationUsageEnum.Values.Require), null => null, _ => throw new InvalidOperationException(), }; /// - /// Applies the fields of to a (create request). + /// Applies the fields of to a . /// - internal static void ApplyToApi(V1ClientGrantConf conf, ClientGrantBase request) + internal static void ApplyToApi(V1ClientGrantConf conf, CreateClientGrantRequestContent request) { - request.Scope = conf.Scope?.ToList() ?? null!; + request.Scope = conf.Scope; request.AllowAnyOrganization = conf.AllowAnyOrganization; request.OrganizationUsage = ToApi(conf.OrganizationUsage); } /// - /// Applies the fields of to a . + /// Converts from a local to an API . /// - internal static void ApplyToApi(V1ClientGrantConf conf, ClientGrantUpdateRequest request) + internal static ClientGrantOrganizationNullableUsageEnum? ToApiNullable(V1ClientGrantOrganizationUsage? source) => source switch { - request.Scope = conf.Scope?.ToList() ?? null!; + V1ClientGrantOrganizationUsage.Deny => new ClientGrantOrganizationNullableUsageEnum(ClientGrantOrganizationNullableUsageEnum.Values.Deny), + V1ClientGrantOrganizationUsage.Allow => new ClientGrantOrganizationNullableUsageEnum(ClientGrantOrganizationNullableUsageEnum.Values.Allow), + V1ClientGrantOrganizationUsage.Require => new ClientGrantOrganizationNullableUsageEnum(ClientGrantOrganizationNullableUsageEnum.Values.Require), + null => null, + _ => throw new InvalidOperationException(), + }; + + /// + /// Applies the fields of to a . + /// + internal static void ApplyToApi(V1ClientGrantConf conf, UpdateClientGrantRequestContent request) + { + request.Scope = conf.Scope; request.AllowAnyOrganization = conf.AllowAnyOrganization; - request.OrganizationUsage = ToApi(conf.OrganizationUsage); + if (conf.OrganizationUsage is not null) + request.OrganizationUsage = ToApiNullable(conf.OrganizationUsage); } /// @@ -114,9 +139,8 @@ internal static void ApplyToApi(V1ClientGrantConf conf, ClientGrantUpdateRequest /// protected override async Task Get(IManagementApiClient api, string id, string defaultNamespace, CancellationToken cancellationToken) { - var list = await api.ClientGrants.GetAllAsync(new GetClientGrantsRequest(), cancellationToken: cancellationToken); - var self = list.FirstOrDefault(i => i.Id == id); - return FromApi(self); + var self = await api.ClientGrants.GetAsync(id, null, cancellationToken); + return FromApi((GetClientGrantResponseContent?)self); } /// @@ -140,8 +164,8 @@ internal static void ApplyToApi(V1ClientGrantConf conf, ClientGrantUpdateRequest if (string.IsNullOrWhiteSpace(audience)) throw new InvalidOperationException(); - var list = await api.ClientGrants.GetAllAsync(new GetClientGrantsRequest() { ClientId = clientId }, null!, cancellationToken); - return list.Where(i => i.ClientId == clientId && i.Audience == audience).Select(i => i.Id).FirstOrDefault(); + var pager = await api.ClientGrants.ListAsync(new ListClientGrantsRequestParameters { ClientId = clientId }, null, cancellationToken); + return pager.CurrentPage.Items?.Where(i => i.ClientId == clientId && i.Audience == audience).Select(i => i.Id).FirstOrDefault(); } /// @@ -160,12 +184,12 @@ internal static void ApplyToApi(V1ClientGrantConf conf, ClientGrantUpdateRequest /// protected override async Task Create(IManagementApiClient api, V1ClientGrantConf conf, string defaultNamespace, CancellationToken cancellationToken) { - var req = new ClientGrantCreateRequest(); - req.ClientId = await ResolveClientRefToId(api, conf.ClientRef, defaultNamespace, cancellationToken) ?? null!; - req.Audience = await ResolveResourceServerRefToIdentifier(api, conf.Audience, defaultNamespace, cancellationToken) ?? null!; + var clientId = await ResolveClientRefToId(api, conf.ClientRef, defaultNamespace, cancellationToken) ?? null!; + var audience = await ResolveResourceServerRefToIdentifier(api, conf.Audience, defaultNamespace, cancellationToken) ?? null!; + var req = new CreateClientGrantRequestContent { ClientId = clientId, Audience = audience }; ApplyToApi(conf, req); - var self = await api.ClientGrants.CreateAsync(req, cancellationToken); + var self = await api.ClientGrants.CreateAsync(req, null, cancellationToken); if (self is null) throw new InvalidOperationException(); @@ -175,16 +199,16 @@ protected override async Task Create(IManagementApiClient api, V1ClientG /// protected override async Task Update(IManagementApiClient api, string id, V1ClientGrantConf? last, V1ClientGrantConf conf, string defaultNamespace, CancellationToken cancellationToken) { - var req = new ClientGrantUpdateRequest(); + var req = new UpdateClientGrantRequestContent(); ApplyToApi(conf, req); - await api.ClientGrants.UpdateAsync(id, req, cancellationToken); + await api.ClientGrants.UpdateAsync(id, req, null, cancellationToken); } /// protected override Task DeletedAsync(IManagementApiClient api, string id, CancellationToken cancellationToken) { - return api.ClientGrants.DeleteAsync(id, cancellationToken); + return api.ClientGrants.DeleteAsync(id, null, cancellationToken); } } diff --git a/src/Alethic.Auth0.Operator/Controllers/V1ConnectionController.cs b/src/Alethic.Auth0.Operator/Controllers/V1ConnectionController.cs deleted file mode 100644 index 7f46176..0000000 --- a/src/Alethic.Auth0.Operator/Controllers/V1ConnectionController.cs +++ /dev/null @@ -1,1096 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -using Alethic.Auth0.Operator.Core.Models; -using Alethic.Auth0.Operator.Core.Models.Connection.V1; -using Alethic.Auth0.Operator.Models; -using Alethic.Auth0.Operator.Options; - -using Auth0.Core.Exceptions; -using Auth0.ManagementApi; -using Auth0.ManagementApi.Models; -using Auth0.ManagementApi.Models.Connections; -using Auth0.ManagementApi.Paging; - -using k8s.Models; - -using KubeOps.Abstractions.Rbac; -using KubeOps.Abstractions.Reconciliation.Controller; -using KubeOps.KubernetesClient; - -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -using Newtonsoft.Json.Linq; - -namespace Alethic.Auth0.Operator.Controllers -{ - - [EntityRbac(typeof(V1Connection), Verbs = RbacVerb.All)] - [EntityRbac(typeof(V2alpha1Tenant), Verbs = RbacVerb.List | RbacVerb.Get)] - [EntityRbac(typeof(V1Secret), Verbs = RbacVerb.List | RbacVerb.Get)] - [EntityRbac(typeof(Eventsv1Event), Verbs = RbacVerb.All)] - public class V1ConnectionController : - V1TenantEntityInstanceController, - IEntityController - { - - /// - /// Initializes a new instance. - /// - /// - /// - /// - /// - public V1ConnectionController(IKubernetesClient kube, IMemoryCache cache, IOptions options, ILogger logger) : - base(kube, cache, options, logger) - { - - } - - /// - protected override string EntityTypeName => "Connection"; - - /// - /// Converts a API response to a . - /// Note: is populated separately and left null here. - /// - internal static V1ConnectionConf? FromApi(Connection? source) - { - if (source is null) - return null; - - return new V1ConnectionConf - { - Name = source.Name, - DisplayName = source.DisplayName, - Strategy = source.Strategy, - Realms = source.Realms, - IsDomainConnection = source.IsDomainConnection, - ShowAsButton = source.ShowAsButton, - ProvisioningTicketUrl = source.ProvisioningTicketUrl, - Options = FromApiOptions(source.Options, source.Strategy), - Metadata = TransformToSystemTextJson(source.Metadata), - }; - } - - internal static V1ConnectionOptions? FromApiOptions(object? source, string? strategy) - { - if (source is null) - return null; - - if (strategy == "auth0") - { - var src = source as ConnectionOptions ?? TransformToNewtonsoftJson(source); - if (src is null) - return null; - - return FromApi(src); - } - else - { - return TransformToSystemTextJson(source); - } - } - - internal static V1ConnectionOptions FromApi(ConnectionOptions source) - { - return new V1ConnectionOptions - { - Validation = source.Validation is { } v ? FromApi(v) : null, - NonPersistentAttributes = source.NonPersistentAttributes, - Precedence = source.Precedence is { } prec ? Array.ConvertAll(prec, FromApi) : null, - Attributes = source.Attributes is { } attr ? FromApi(attr) : null, - EnableScriptContext = source.EnableScriptContext, - EnableDatabaseCustomization = source.EnableDatabaseCustomization, - ImportMode = source.ImportMode, - CustomScripts = source.CustomScripts is { } cs ? FromApi(cs) : null, - AuthenticationMethods = source.AuthenticationMethods is { } am ? FromApi(am) : null, - PasskeyOptions = source.PasskeyOptions is { } po ? FromApi(po) : null, - PasswordPolicy = source.PasswordPolicy is { } pp ? FromApi(pp) : null, - PasswordComplexityOptions = source.PasswordComplexityOptions is { } pco ? FromApi(pco) : null, - PasswordHistory = source.PasswordHistory is { } ph ? FromApi(ph) : null, - PasswordNoPersonalInfo = source.PasswordNoPersonalInfo is { } pnpi ? FromApi(pnpi) : null, - PasswordDictionary = source.PasswordDictionary is { } pd ? FromApi(pd) : null, - ApiEnableUsers = source.ApiEnableUsers, - BasicProfile = source.BasicProfile, - ExtAdmin = source.ExtAdmin, - ExtIsSuspended = source.ExtIsSuspended, - ExtAgreedTerms = source.ExtAgreedTerms, - ExtGroups = source.ExtGroups, - ExtAssignedPlans = source.ExtAssignedPlans, - ExtProfile = source.ExtProfile, - DisableSelfServiceChangePassword = source.DisableSelfServiceChangePassword, - UpstreamParams = source.UpstreamParams, - SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, - GatewayAuthentication = source.GatewayAuthentication is { } ga ? FromApi(ga) : null, - }; - } - - internal static V1ConnectionOptionsValidation FromApi(ConnectionOptionsValidation source) - { - return new V1ConnectionOptionsValidation - { - UserName = source.UserName is { } u ? FromApi(u) : null, - }; - } - - internal static V1ConnectionOptionsUserName FromApi(ConnectionOptionsUserName source) - { - return new V1ConnectionOptionsUserName - { - Min = source.Min, - Max = source.Max, - }; - } - - internal static V1ConnectionOptionsAttributes FromApi(ConnectionOptionsAttributes source) - { - return new V1ConnectionOptionsAttributes - { - Email = source.Email is { } e ? FromApi(e) : null, - PhoneNumber = source.PhoneNumber is { } p ? FromApi(p) : null, - Username = source.Username is { } u ? FromApi(u) : null, - }; - } - - internal static V1ConnectionOptionsEmailAttribute FromApi(ConnectionOptionsEmailAttribute source) - { - return new V1ConnectionOptionsEmailAttribute - { - Identifier = source.Identifier is { } i ? FromApi(i) : null, - ProfileRequired = source.ProfileRequired, - Signup = source.Signup is { } s ? FromApi(s) : null, - }; - } - - internal static V1ConnectionOptionsEmailSignup FromApi(ConnectionOptionsEmailSignup source) - { - return new V1ConnectionOptionsEmailSignup - { - Status = FromApi(source.Status), - Verification = source.Verification is { } v ? FromApi(v) : null, - }; - } - - internal static V1ConnectionOptionsPhoneNumberAttribute FromApi(ConnectionOptionsPhoneNumberAttribute source) - { - return new V1ConnectionOptionsPhoneNumberAttribute - { - Signup = source.Signup is { } s ? FromApi(s) : null, - }; - } - - internal static V1ConnectionOptionsPhoneNumberSignup FromApi(ConnectionOptionsPhoneNumberSignup source) - { - return new V1ConnectionOptionsPhoneNumberSignup - { - Status = FromApi(source.Status), - Verification = source.Verification is { } v ? FromApi(v) : null, - }; - } - - internal static V1ConnectionOptionsUsernameAttribute FromApi(ConnectionOptionsUsernameAttribute source) - { - return new V1ConnectionOptionsUsernameAttribute - { - Identifier = source.Identifier is { } i ? FromApi(i) : null, - ProfileRequired = source.ProfileRequired, - Signup = source.Signup is { } s ? FromApi(s) : null, - Validation = source.Validation is { } v ? FromApi(v) : null, - }; - } - - internal static V1ConnectionOptionsUsernameSignup FromApi(ConnectionOptionsUsernameSignup source) - { - return new V1ConnectionOptionsUsernameSignup - { - Status = FromApi(source.Status), - }; - } - - internal static V1ConnectionOptionsAttributeIdentifier FromApi(ConnectionOptionsAttributeIdentifier source) - { - return new V1ConnectionOptionsAttributeIdentifier - { - Active = source.Active, - }; - } - - internal static V1ConnectionOptionsAttributeValidation FromApi(ConnectionOptionsAttributeValidation source) - { - return new V1ConnectionOptionsAttributeValidation - { - MinLength = source.MinLength, - MaxLength = source.MaxLength, - AllowedTypes = source.AllowedTypes is { } at ? FromApi(at) : null, - }; - } - - internal static V1ConnectionOptionsAttributeAllowedTypes FromApi(ConnectionOptionsAttributeAllowedTypes source) - { - return new V1ConnectionOptionsAttributeAllowedTypes - { - Email = source.Email, - PhoneNumber = source.PhoneNumber, - }; - } - - internal static V1ConnectionOptionsVerification FromApi(ConnectionOptionsVerification source) - { - return new V1ConnectionOptionsVerification - { - Active = source.Active, - }; - } - - internal static V1ConnectionOptionsCustomScripts FromApi(ConnectionOptionsCustomScripts source) - { - return new V1ConnectionOptionsCustomScripts - { - Login = source.Login, - GetUser = source.GetUser, - Delete = source.Delete, - ChangePassword = source.ChangePassword, - Verify = source.Verify, - Create = source.Create, - ChangeUsername = source.ChangeUsername, - ChangeEmail = source.ChangeEmail, - ChangePhoneNumber = source.ChangePhoneNumber, - }; - } - - internal static V1ConnectionOptionsAuthenticationMethods FromApi(ConnectionOptionsAuthenticationMethods source) - { - return new V1ConnectionOptionsAuthenticationMethods - { - Password = source.Password is { } p ? FromApi(p) : null, - Passkey = source.Passkey is { } pk ? FromApi(pk) : null, - }; - } - - internal static V1ConnectionOptionsPasswordAuthenticationMethod FromApi(ConnectionOptionsPasswordAuthenticationMethod source) - { - return new V1ConnectionOptionsPasswordAuthenticationMethod - { - Enabled = source.Enabled, - }; - } - - internal static V1ConnectionOptionsPasskeyAuthenticationMethod FromApi(ConnectionOptionsPasskeyAuthenticationMethod source) - { - return new V1ConnectionOptionsPasskeyAuthenticationMethod - { - Enabled = source.Enabled, - }; - } - - internal static V1ConnectionOptionsPasskeyOptions FromApi(ConnectionOptionsPasskeyOptions source) - { - return new V1ConnectionOptionsPasskeyOptions - { - ChallengeUi = FromApi(source.ChallengeUi), - ProgressiveEnrollmentEnabled = source.ProgressiveEnrollmentEnabled, - LocalEnrollmentEnabled = source.LocalEnrollmentEnabled, - }; - } - - internal static V1ConnectionOptionsPasswordComplexityOptions FromApi(ConnectionOptionsPasswordComplexityOptions source) - { - return new V1ConnectionOptionsPasswordComplexityOptions - { - MinLength = source.MinLength, - }; - } - - internal static V1ConnectionOptionsPasswordHistory FromApi(ConnectionOptionsPasswordHistory source) - { - return new V1ConnectionOptionsPasswordHistory - { - Enable = source.Enable, - Size = source.Size, - }; - } - - internal static V1ConnectionOptionsPasswordNoPersonalInfo FromApi(ConnectionOptionsPasswordNoPersonalInfo source) - { - return new V1ConnectionOptionsPasswordNoPersonalInfo - { - Enable = source.Enable, - }; - } - - internal static V1ConnectionOptionsPasswordDictionary FromApi(ConnectionOptionsPasswordDictionary source) - { - return new V1ConnectionOptionsPasswordDictionary - { - Enable = source.Enable, - Dictionary = source.Dictionary, - }; - } - - internal static V1ConnectionGatewayAuthentication FromApi(GatewayAuthentication source) - { - return new V1ConnectionGatewayAuthentication - { - Method = source.Method, - Subject = source.Subject, - Audience = source.Audience, - Secret = source.Secret, - SecretBase64Encoded = source.SecretBase64Encoded, - }; - } - - internal static V1ConnectionOptionsPrecedence FromApi(ConnectionOptionsPrecedence source) => source switch - { - ConnectionOptionsPrecedence.Email => V1ConnectionOptionsPrecedence.Email, - ConnectionOptionsPrecedence.PhoneNumber => V1ConnectionOptionsPrecedence.PhoneNumber, - ConnectionOptionsPrecedence.UserName => V1ConnectionOptionsPrecedence.UserName, - _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), - }; - - internal static ConnectionOptionsPrecedence ToApi(V1ConnectionOptionsPrecedence source) => source switch - { - V1ConnectionOptionsPrecedence.Email => ConnectionOptionsPrecedence.Email, - V1ConnectionOptionsPrecedence.PhoneNumber => ConnectionOptionsPrecedence.PhoneNumber, - V1ConnectionOptionsPrecedence.UserName => ConnectionOptionsPrecedence.UserName, - _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), - }; - - internal static V1ConnectionOptionsAttributeStatus FromApi(ConnectionOptionsAttributeStatus source) => source switch - { - ConnectionOptionsAttributeStatus.Required => V1ConnectionOptionsAttributeStatus.Required, - ConnectionOptionsAttributeStatus.Optional => V1ConnectionOptionsAttributeStatus.Optional, - ConnectionOptionsAttributeStatus.Inactive => V1ConnectionOptionsAttributeStatus.Inactive, - _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), - }; - - internal static ConnectionOptionsAttributeStatus ToApi(V1ConnectionOptionsAttributeStatus source) => source switch - { - V1ConnectionOptionsAttributeStatus.Required => ConnectionOptionsAttributeStatus.Required, - V1ConnectionOptionsAttributeStatus.Optional => ConnectionOptionsAttributeStatus.Optional, - V1ConnectionOptionsAttributeStatus.Inactive => ConnectionOptionsAttributeStatus.Inactive, - _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), - }; - - internal static V1ConnectionOptionsPasswordPolicy FromApi(ConnectionOptionsPasswordPolicy source) => source switch - { - ConnectionOptionsPasswordPolicy.None => V1ConnectionOptionsPasswordPolicy.None, - ConnectionOptionsPasswordPolicy.Low => V1ConnectionOptionsPasswordPolicy.Low, - ConnectionOptionsPasswordPolicy.Fair => V1ConnectionOptionsPasswordPolicy.Fair, - ConnectionOptionsPasswordPolicy.Good => V1ConnectionOptionsPasswordPolicy.Good, - ConnectionOptionsPasswordPolicy.Excellent => V1ConnectionOptionsPasswordPolicy.Excellent, - _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), - }; - - internal static ConnectionOptionsPasswordPolicy ToApi(V1ConnectionOptionsPasswordPolicy source) => source switch - { - V1ConnectionOptionsPasswordPolicy.None => ConnectionOptionsPasswordPolicy.None, - V1ConnectionOptionsPasswordPolicy.Low => ConnectionOptionsPasswordPolicy.Low, - V1ConnectionOptionsPasswordPolicy.Fair => ConnectionOptionsPasswordPolicy.Fair, - V1ConnectionOptionsPasswordPolicy.Good => ConnectionOptionsPasswordPolicy.Good, - V1ConnectionOptionsPasswordPolicy.Excellent => ConnectionOptionsPasswordPolicy.Excellent, - _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), - }; - - internal static V1ConnectionSetUserRootAttributes FromApi(SetUserRootAttributes source) => source switch - { - SetUserRootAttributes.OnEachLogin => V1ConnectionSetUserRootAttributes.OnEachLogin, - SetUserRootAttributes.OnFirstLogin => V1ConnectionSetUserRootAttributes.OnFirstLogin, - SetUserRootAttributes.NeverOnLogin => V1ConnectionSetUserRootAttributes.NeverOnLogin, - _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), - }; - - internal static SetUserRootAttributes ToApi(V1ConnectionSetUserRootAttributes source) => source switch - { - V1ConnectionSetUserRootAttributes.OnEachLogin => SetUserRootAttributes.OnEachLogin, - V1ConnectionSetUserRootAttributes.OnFirstLogin => SetUserRootAttributes.OnFirstLogin, - V1ConnectionSetUserRootAttributes.NeverOnLogin => SetUserRootAttributes.NeverOnLogin, - _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), - }; - - internal static V1ConnectionChallengeUi FromApi(ChallengeUi source) => source switch - { - ChallengeUi.Both => V1ConnectionChallengeUi.Both, - ChallengeUi.AutoFill => V1ConnectionChallengeUi.AutoFill, - ChallengeUi.Button => V1ConnectionChallengeUi.Button, - _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), - }; - - internal static ChallengeUi ToApi(V1ConnectionChallengeUi source) => source switch - { - V1ConnectionChallengeUi.Both => ChallengeUi.Both, - V1ConnectionChallengeUi.AutoFill => ChallengeUi.AutoFill, - V1ConnectionChallengeUi.Button => ChallengeUi.Button, - _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), - }; - - /// - /// Gets the list of enabled client IDs for the specified connection. - /// - /// - /// - /// - /// - async Task GetEnabledClientsAsync(IManagementApiClient api, string connectionId, CancellationToken cancellationToken) - { - var clients = await api.Connections.GetEnabledClientsAsync(new EnabledClientsGetRequest() { ConnectionId = connectionId }, cancellationToken: cancellationToken); - - var l = new List(clients.Count); - foreach (var client in clients) - if (client.ClientId is not null) - l.Add(client.ClientId); - - return l.ToArray(); - } - - /// - protected override async Task Get(IManagementApiClient api, string id, string defaultNamespace, CancellationToken cancellationToken) - { - try - { - var self = await api.Connections.GetAsync(id, cancellationToken: cancellationToken); - if (self == null) - return null; - - var conf = FromApi(self)!; - conf.EnabledClients = (await GetEnabledClientsAsync(api, self.Id, cancellationToken)) - .Select(i => new V1ClientReference() { Id = i }) - .ToArray(); - return conf; - } - catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) - { - return null; - } - } - - /// - protected override async Task Find(IManagementApiClient api, V1Connection entity, V1Connection.SpecDef spec, string defaultNamespace, CancellationToken cancellationToken) - { - if (spec.Find is not null) - { - if (spec.Find.ConnectionId is string connectionId) - { - try - { - var connection = await api.Connections.GetAsync(connectionId, cancellationToken: cancellationToken); - Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} found existing connection: {Name}", EntityTypeName, entity.Namespace(), entity.Name(), connection.Name); - return connection.Id; - } - catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) - { - Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} could not find connection with id {ConnectionId}.", EntityTypeName, entity.Namespace(), entity.Name(), connectionId); - return null; - } - } - - return null; - } - else - { - var conf = spec.Init ?? spec.Conf; - if (conf is null || string.IsNullOrEmpty(conf.Name)) - return null; - - var list = await api.Connections.GetAllAsync(new GetConnectionsRequest(), (PaginationInfo?)null!, cancellationToken: cancellationToken); - var self = list.FirstOrDefault(i => i.Name == conf.Name); - if (self is not null) - Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} found existing connection by name: {Name}", EntityTypeName, entity.Namespace(), entity.Name(), conf.Name); - - return self?.Id; - } - } - - /// - protected override string? ValidateCreate(V1ConnectionConf conf) - { - return null; - } - - /// - /// Attempts to resolve the list of client references to client IDs. - /// - /// - /// - /// - /// - /// - /// - async Task ResolveClientRefsToIds(IManagementApiClient api, V1ClientReference[]? refs, string defaultNamespace, CancellationToken cancellationToken) - { - if (refs is null) - return Array.Empty(); - - var l = new List(refs.Length); - - foreach (var i in refs) - l.Add(await ResolveClientRefToId(api, i, defaultNamespace, cancellationToken) ?? throw new InvalidOperationException()); - - return l.ToArray(); - } - - /// - protected override async Task Create(IManagementApiClient api, V1ConnectionConf conf, string defaultNamespace, CancellationToken cancellationToken) - { - Logger.LogInformation("{EntityTypeName} creating connection in Auth0 with name: {ConnectionName} and strategy: {Strategy}", EntityTypeName, conf.Name, conf.Strategy); - - if (conf.Strategy is null) - throw new InvalidOperationException("Missing connection strategy."); - - if (conf.Options is null) - throw new InvalidOperationException("Missing connection options."); - - var req = new ConnectionCreateRequest(); - ApplyToApi(conf, req); - - req.Strategy = conf.Strategy; - - // calculate options: depends on current strategy, but we need to potentially patch the existing resource - if (conf.Options is not null) - { - if (conf.Strategy == "auth0") - { - req.Options = new ConnectionOptions(); - ApplyToApi(conf.Options, (ConnectionOptions)req.Options); - } - else - { - var options = (dynamic)new JObject(); - req.Options = options; - ApplyToApi(conf.Options, ref options); - } - } - - var self = await api.Connections.CreateAsync(req, cancellationToken); - if (self is null) - throw new InvalidOperationException(); - - Logger.LogInformation("{EntityTypeName} successfully created connection in Auth0 with ID: {ConnectionId}, name: {ConnectionName} and strategy: {Strategy}", EntityTypeName, self.Id, conf.Name, conf.Strategy); - return self.Id; - } - - /// - protected override async Task Update(IManagementApiClient api, string id, V1ConnectionConf? last, V1ConnectionConf conf, string defaultNamespace, CancellationToken cancellationToken) - { - Logger.LogInformation("{EntityTypeName} updating connection in Auth0 with ID: {ConnectionId}, name: {ConnectionName} and strategy: {Strategy}", EntityTypeName, id, conf.Name, conf.Strategy); - - var req = new ConnectionUpdateRequest(); - ApplyToApi(conf, req); - - // name has to be cleared for an update - req.Name = null!; - - // calculate options: depends on current strategy, but we need to potentially patch the existing resource - if (conf.Options is not null) - { - var current = await api.Connections.GetAsync(id, cancellationToken: cancellationToken); - if (current.Strategy == "auth0") - { - var options = (ConnectionOptions)current.Options ?? new ConnectionOptions(); - req.Options = options; - ApplyToApi(conf.Options, options); - } - else - { - var options = (dynamic)((JObject?)current.Options ?? new JObject()); - req.Options = options; - ApplyToApi(conf.Options, ref options); - } - } - - await api.Connections.UpdateAsync(id, req, cancellationToken); - await UpdateEnabledClientsAsync(api, id, conf, defaultNamespace, cancellationToken); - - Logger.LogInformation("{EntityTypeName} successfully updated connection in Auth0 with ID: {ConnectionId}, name: {ConnectionName} and strategy: {Strategy}", EntityTypeName, id, conf.Name, conf.Strategy); - } - - /// - /// Applies the specified configuration to the request object. - /// - /// - /// - internal static void ApplyToApi(V1ConnectionConf source, ConnectionBase target) - { - if (source.Name is { } name) - target.Name = name; - - if (source.DisplayName is { } displayName) - target.DisplayName = displayName; - - if (source.Metadata is { } metadata) - target.Metadata = metadata; - - if (source.Realms is { } realms) - target.Realms = realms; - - if (source.IsDomainConnection is not null) - target.IsDomainConnection = source.IsDomainConnection ?? false; - - if (source.ShowAsButton is { } showAsButton) - target.ShowAsButton = showAsButton; - } - - void ApplyToApi(V1ConnectionOptions source, ConnectionOptions target) - { - if (source.Validation is { } validation) - { - target.Validation ??= new ConnectionOptionsValidation(); - ApplyToApi(validation, target.Validation); - } - - if (source.NonPersistentAttributes is { } nonPersistentAttributes) - target.NonPersistentAttributes = nonPersistentAttributes; - - if (source.Precedence is { } precedence) - target.Precedence = Array.ConvertAll(precedence, ToApi); - - if (source.Attributes is { } attributes) - { - target.Attributes ??= new ConnectionOptionsAttributes(); - ApplyToApi(attributes, target.Attributes); - } - - if (source.EnableScriptContext is { } enableScriptContext) - target.EnableScriptContext = enableScriptContext; - - if (source.EnableDatabaseCustomization is { } enableDatabaseCustomization) - target.EnableDatabaseCustomization = enableDatabaseCustomization; - - if (source.ImportMode is { } importMode) - target.ImportMode = importMode; - - if (source.CustomScripts is { } customScripts) - { - target.CustomScripts ??= new ConnectionOptionsCustomScripts(); - ApplyToApi(customScripts, target.CustomScripts); - } - - if (source.AuthenticationMethods is { } authenticationMethods) - { - target.AuthenticationMethods ??= new ConnectionOptionsAuthenticationMethods(); - ApplyToApi(authenticationMethods, target.AuthenticationMethods); - } - - if (source.PasskeyOptions is { } passkeyOptions) - { - target.PasskeyOptions ??= new ConnectionOptionsPasskeyOptions(); - ApplyToApi(passkeyOptions, target.PasskeyOptions); - } - - if (source.PasswordPolicy is { } passwordPolicy) - target.PasswordPolicy = ToApi(passwordPolicy); - - if (source.PasswordComplexityOptions is { } passwordComplexityOptions) - { - target.PasswordComplexityOptions ??= new ConnectionOptionsPasswordComplexityOptions(); - ApplyToApi(passwordComplexityOptions, target.PasswordComplexityOptions); - } - - if (source.PasswordHistory is { } passwordHistory) - { - target.PasswordHistory ??= new ConnectionOptionsPasswordHistory(); - ApplyToApi(passwordHistory, target.PasswordHistory); - } - - if (source.PasswordNoPersonalInfo is { } passwordNoPersonalInfo) - { - target.PasswordNoPersonalInfo ??= new ConnectionOptionsPasswordNoPersonalInfo(); - ApplyToApi(passwordNoPersonalInfo, target.PasswordNoPersonalInfo); - } - - if (source.PasswordDictionary is { } passwordDictionary) - { - target.PasswordDictionary ??= new ConnectionOptionsPasswordDictionary(); - ApplyToApi(passwordDictionary, target.PasswordDictionary); - } - - if (source.ApiEnableUsers is { } apiEnableUsers) - target.ApiEnableUsers = apiEnableUsers; - - if (source.BasicProfile is { } basicProfile) - target.BasicProfile = basicProfile; - - if (source.ExtAdmin is { } extAdmin) - target.ExtAdmin = extAdmin; - - if (source.ExtIsSuspended is { } extIsSuspended) - target.ExtIsSuspended = extIsSuspended; - - if (source.ExtAgreedTerms is { } extAgreedTerms) - target.ExtAgreedTerms = extAgreedTerms; - - if (source.ExtGroups is { } extGroups) - target.ExtGroups = extGroups; - - if (source.ExtAssignedPlans is { } extAssignedPlans) - target.ExtAssignedPlans = extAssignedPlans; - - if (source.ExtProfile is { } extProfile) - target.ExtProfile = extProfile; - - if (source.DisableSelfServiceChangePassword is { } disableSelfServiceChangePassword) - target.DisableSelfServiceChangePassword = disableSelfServiceChangePassword; - - if (source.UpstreamParams is { } upstreamParams) - target.UpstreamParams = upstreamParams; - - if (source.SetUserRootAttributes is { } setUserRootAttributes) - target.SetUserRootAttributes = ToApi(setUserRootAttributes); - - if (source.GatewayAuthentication is { } gatewayAuthentication) - { - target.GatewayAuthentication ??= new GatewayAuthentication(); - ApplyToApi(gatewayAuthentication, target.GatewayAuthentication); - } - } - - static void ApplyToApi(V1ConnectionOptionsValidation source, ConnectionOptionsValidation target) - { - if (source.UserName is { } userName) - { - target.UserName ??= new ConnectionOptionsUserName(); - ApplyToApi(userName, target.UserName); - } - } - - static void ApplyToApi(V1ConnectionOptionsUserName source, ConnectionOptionsUserName target) - { - if (source.Min is { } min) - target.Min = min; - - if (source.Max is { } max) - target.Max = max; - } - - static void ApplyToApi(V1ConnectionOptionsAttributes source, ConnectionOptionsAttributes target) - { - if (source.Email is { } email) - { - target.Email ??= new ConnectionOptionsEmailAttribute(); - ApplyToApi(email, target.Email); - } - - if (source.PhoneNumber is { } phoneNumber) - { - target.PhoneNumber ??= new ConnectionOptionsPhoneNumberAttribute(); - ApplyToApi(phoneNumber, target.PhoneNumber); - } - - if (source.Username is { } username) - { - target.Username ??= new ConnectionOptionsUsernameAttribute(); - ApplyToApi(username, target.Username); - } - } - - static void ApplyToApi(V1ConnectionOptionsEmailAttribute source, ConnectionOptionsEmailAttribute target) - { - if (source.Identifier is { } identifier) - { - target.Identifier ??= new ConnectionOptionsAttributeIdentifier(); - ApplyToApi(identifier, target.Identifier); - } - - if (source.ProfileRequired is { } profileRequired) - target.ProfileRequired = profileRequired; - - if (source.Signup is { } signup) - { - target.Signup ??= new ConnectionOptionsEmailSignup(); - ApplyToApi(signup, target.Signup); - } - } - - static void ApplyToApi(V1ConnectionOptionsEmailSignup source, ConnectionOptionsEmailSignup target) - { - if (source.Status is { } status) - target.Status = ToApi(status); - - if (source.Verification is { } verification) - { - target.Verification ??= new ConnectionOptionsVerification(); - ApplyToApi(verification, target.Verification); - } - } - - static void ApplyToApi(V1ConnectionOptionsPhoneNumberAttribute source, ConnectionOptionsPhoneNumberAttribute target) - { - if (source.Signup is { } signup) - { - target.Signup ??= new ConnectionOptionsPhoneNumberSignup(); - ApplyToApi(signup, target.Signup); - } - } - - static void ApplyToApi(V1ConnectionOptionsPhoneNumberSignup source, ConnectionOptionsPhoneNumberSignup target) - { - if (source.Status is { } status) - target.Status = ToApi(status); - - if (source.Verification is { } verification) - { - target.Verification ??= new ConnectionOptionsVerification(); - ApplyToApi(verification, target.Verification); - } - } - - static void ApplyToApi(V1ConnectionOptionsUsernameAttribute source, ConnectionOptionsUsernameAttribute target) - { - if (source.Identifier is { } identifier) - { - target.Identifier ??= new ConnectionOptionsAttributeIdentifier(); - ApplyToApi(identifier, target.Identifier); - } - - if (source.ProfileRequired is { } profileRequired) - target.ProfileRequired = profileRequired; - - if (source.Signup is { } signup) - { - target.Signup ??= new ConnectionOptionsUsernameSignup(); - ApplyToApi(signup, target.Signup); - } - - if (source.Validation is { } validation) - { - target.Validation ??= new ConnectionOptionsAttributeValidation(); - ApplyToApi(validation, target.Validation); - } - } - - static void ApplyToApi(V1ConnectionOptionsUsernameSignup source, ConnectionOptionsUsernameSignup target) - { - if (source.Status is { } status) - target.Status = ToApi(status); - } - - static void ApplyToApi(V1ConnectionOptionsAttributeIdentifier source, ConnectionOptionsAttributeIdentifier target) - { - if (source.Active is { } active) - target.Active = active; - } - - static void ApplyToApi(V1ConnectionOptionsAttributeValidation source, ConnectionOptionsAttributeValidation target) - { - if (source.MinLength is { } minLength) - target.MinLength = minLength; - - if (source.MaxLength is { } maxLength) - target.MaxLength = maxLength; - - if (source.AllowedTypes is { } allowedTypes) - { - target.AllowedTypes ??= new ConnectionOptionsAttributeAllowedTypes(); - ApplyToApi(allowedTypes, target.AllowedTypes); - } - } - - static void ApplyToApi(V1ConnectionOptionsAttributeAllowedTypes source, ConnectionOptionsAttributeAllowedTypes target) - { - if (source.Email is { } email) - target.Email = email; - - if (source.PhoneNumber is { } phoneNumber) - target.PhoneNumber = phoneNumber; - } - - static void ApplyToApi(V1ConnectionOptionsVerification source, ConnectionOptionsVerification target) - { - if (source.Active is { } active) - target.Active = active; - } - - static void ApplyToApi(V1ConnectionOptionsCustomScripts source, ConnectionOptionsCustomScripts target) - { - if (source.Login is { } login) - target.Login = login; - - if (source.GetUser is { } getUser) - target.GetUser = getUser; - - if (source.Delete is { } delete) - target.Delete = delete; - - if (source.ChangePassword is { } changePassword) - target.ChangePassword = changePassword; - - if (source.Verify is { } verify) - target.Verify = verify; - - if (source.Create is { } create) - target.Create = create; - - if (source.ChangeUsername is { } changeUsername) - target.ChangeUsername = changeUsername; - - if (source.ChangeEmail is { } changeEmail) - target.ChangeEmail = changeEmail; - - if (source.ChangePhoneNumber is { } changePhoneNumber) - target.ChangePhoneNumber = changePhoneNumber; - } - - static void ApplyToApi(V1ConnectionOptionsAuthenticationMethods source, ConnectionOptionsAuthenticationMethods target) - { - if (source.Password is { } password) - { - target.Password ??= new ConnectionOptionsPasswordAuthenticationMethod(); - ApplyToApi(password, target.Password); - } - - if (source.Passkey is { } passkey) - { - target.Passkey ??= new ConnectionOptionsPasskeyAuthenticationMethod(); - ApplyToApi(passkey, target.Passkey); - } - } - - static void ApplyToApi(V1ConnectionOptionsPasswordAuthenticationMethod source, ConnectionOptionsPasswordAuthenticationMethod target) - { - if (source.Enabled is { } enabled) - target.Enabled = enabled; - } - - static void ApplyToApi(V1ConnectionOptionsPasskeyAuthenticationMethod source, ConnectionOptionsPasskeyAuthenticationMethod target) - { - if (source.Enabled is { } enabled) - target.Enabled = enabled; - } - - static void ApplyToApi(V1ConnectionOptionsPasskeyOptions source, ConnectionOptionsPasskeyOptions target) - { - if (source.ChallengeUi is { } challengeUi) - target.ChallengeUi = ToApi(challengeUi); - - if (source.ProgressiveEnrollmentEnabled is { } progressiveEnrollmentEnabled) - target.ProgressiveEnrollmentEnabled = progressiveEnrollmentEnabled; - - if (source.LocalEnrollmentEnabled is { } localEnrollmentEnabled) - target.LocalEnrollmentEnabled = localEnrollmentEnabled; - } - - static void ApplyToApi(V1ConnectionOptionsPasswordComplexityOptions source, ConnectionOptionsPasswordComplexityOptions target) - { - if (source.MinLength is { } minLength) - target.MinLength = minLength; - } - - static void ApplyToApi(V1ConnectionOptionsPasswordHistory source, ConnectionOptionsPasswordHistory target) - { - if (source.Enable is { } enable) - target.Enable = enable; - - if (source.Size is { } size) - target.Size = size; - } - - static void ApplyToApi(V1ConnectionOptionsPasswordNoPersonalInfo source, ConnectionOptionsPasswordNoPersonalInfo target) - { - if (source.Enable is { } enable) - target.Enable = enable; - } - - static void ApplyToApi(V1ConnectionOptionsPasswordDictionary source, ConnectionOptionsPasswordDictionary target) - { - if (source.Enable is { } enable) - target.Enable = enable; - - if (source.Dictionary is { } dictionary) - target.Dictionary = dictionary; - } - - static void ApplyToApi(V1ConnectionGatewayAuthentication source, GatewayAuthentication target) - { - if (source.Method is { } method) - target.Method = method; - - if (source.Subject is { } subject) - target.Subject = subject; - - if (source.Audience is { } audience) - target.Audience = audience; - - if (source.Secret is { } secret) - target.Secret = secret; - - if (source.SecretBase64Encoded is { } secretBase64Encoded) - target.SecretBase64Encoded = secretBase64Encoded; - } - - static void ApplyToApi(V1ConnectionOptions source, ref dynamic target) - { - var patch = TransformToNewtonsoftJson(source); - if (patch is null) - return; - - if (target is not JObject targetObj) - targetObj = new JObject(); - - MergeJObject(patch, targetObj); - target = targetObj; - } - - static void MergeJObject(JObject source, JObject target) - { - foreach (var property in source.Properties()) - { - if (target[property.Name] is JObject existingObj && property.Value is JObject sourceObj) - MergeJObject(sourceObj, existingObj); - else - target[property.Name] = property.Value; - } - } - - /// - /// Applies the update of enabled clients. - /// - /// - /// - /// - /// - /// - /// - async Task UpdateEnabledClientsAsync(IManagementApiClient api, string id, V1ConnectionConf conf, string defaultNamespace, CancellationToken cancellationToken) - { - if (conf.EnabledClients is not null) - { - var req = new List(); - - // apply existing clients, disabled by default - foreach (var current in await api.Connections.GetEnabledClientsAsync(new() { ConnectionId = id }, cancellationToken: cancellationToken)) - if (current.ClientId is not null) - req.Add(new() { ClientId = current.ClientId, Status = false }); - - // add or enable clients specified in the configuration - foreach (var clientId in await ResolveClientRefsToIds(api, conf.EnabledClients, defaultNamespace, cancellationToken)) - { - var existing = req.FirstOrDefault(i => i.ClientId == clientId); - if (existing is null) - req.Add(existing = new() { ClientId = clientId }); - - existing.Status = true; - } - - // apply update - if (req.Count > 0) - await api.Connections.UpdateEnabledClientsAsync(id, new() { EnabledClients = req }, cancellationToken: cancellationToken); - } - } - - /// - protected override async Task DeletedAsync(IManagementApiClient api, string id, CancellationToken cancellationToken) - { - Logger.LogInformation("{EntityTypeName} deleting connection from Auth0 with ID: {ConnectionId} (reason: Kubernetes entity deleted)", EntityTypeName, id); - await api.Connections.DeleteAsync(id, cancellationToken); - Logger.LogInformation("{EntityTypeName} successfully deleted connection from Auth0 with ID: {ConnectionId}", EntityTypeName, id); - } - - } - -} diff --git a/src/Alethic.Auth0.Operator/Controllers/V1ResourceServerController.cs b/src/Alethic.Auth0.Operator/Controllers/V1ResourceServerController.cs index 3b45e71..b2d40ce 100644 --- a/src/Alethic.Auth0.Operator/Controllers/V1ResourceServerController.cs +++ b/src/Alethic.Auth0.Operator/Controllers/V1ResourceServerController.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; @@ -12,7 +11,6 @@ using Auth0.Core.Exceptions; using Auth0.ManagementApi; -using Auth0.ManagementApi.Models; using k8s.Models; @@ -39,162 +37,276 @@ public class V1ResourceServerController : /// /// Transforms the Auth0 Management API resource server model to the operator's resource server configuration model. /// + [return: NotNullIfNotNull(nameof(source))] + internal static V1ResourceServerConf? FromApi(GetResourceServerResponseContent? source) => source is null ? null : new() + { + Id = source.Id, + Identifier = source.Identifier, + Name = source.Name, + Scopes = source.Scopes?.Select(FromApi).ToArray(), + SigningAlgorithm = FromApi(source.SigningAlg), + SigningSecret = source.SigningSecret, + TokenLifetime = source.TokenLifetime, + TokenLifetimeForWeb = source.TokenLifetimeForWeb, + AllowOfflineAccess = source.AllowOfflineAccess, + AllowOnlineAccess = source.AllowOnlineAccess, + AllowOnlineAccessWithEphemeralSessions = source.AllowOnlineAccessWithEphemeralSessions, + SkipConsentForVerifiableFirstPartyClients = source.SkipConsentForVerifiableFirstPartyClients, + TokenDialect = source.TokenDialect is { } td ? FromApi(td) : null, + EnforcePolicies = source.EnforcePolicies, + ConsentPolicy = source.ConsentPolicy.IsDefined && source.ConsentPolicy.Value is { } cp ? FromApi(cp) : null, + AuthorizationDetails = null, + AuthorizationPolicy = source.AuthorizationPolicy.IsDefined && source.AuthorizationPolicy.Value is { } ap ? FromApi(ap) : null, + SubjectTypeAuthorization = FromApi(source.SubjectTypeAuthorization), + TokenEncryption = source.TokenEncryption.IsDefined && source.TokenEncryption.Value is { } te ? FromApi(te) : null, + ProofOfPossession = source.ProofOfPossession.IsDefined && source.ProofOfPossession.Value is { } pop ? FromApi(pop) : null, + }; + [return: NotNullIfNotNull(nameof(source))] internal static V1ResourceServerConf? FromApi(ResourceServer? source) => source is null ? null : new() { Id = source.Id, Identifier = source.Identifier, Name = source.Name, - Scopes = source.Scopes?.Select(FromApi).ToList(), - SigningAlgorithm = FromApi(source.SigningAlgorithm), + Scopes = source.Scopes?.Select(FromApi).ToArray(), + SigningAlgorithm = FromApi(source.SigningAlg), SigningSecret = source.SigningSecret, TokenLifetime = source.TokenLifetime, TokenLifetimeForWeb = source.TokenLifetimeForWeb, AllowOfflineAccess = source.AllowOfflineAccess, + AllowOnlineAccess = source.AllowOnlineAccess, + AllowOnlineAccessWithEphemeralSessions = source.AllowOnlineAccessWithEphemeralSessions, SkipConsentForVerifiableFirstPartyClients = source.SkipConsentForVerifiableFirstPartyClients, - VerificationLocation = source.VerificationLocation, - TokenDialect = FromApi(source.TokenDialect), + TokenDialect = source.TokenDialect is { } td ? FromApi(td) : null, EnforcePolicies = source.EnforcePolicies, - ConsentPolicy = FromApi(source.ConsentPolicy), - AuthorizationDetails = source.AuthorizationDetails?.Select(FromApi).ToList(), - TokenEncryption = FromApi(source.TokenEncryption), - ProofOfPossession = FromApi(source.ProofOfPossession), + ConsentPolicy = source.ConsentPolicy.IsDefined && source.ConsentPolicy.Value is { } cp ? FromApi(cp) : null, + AuthorizationPolicy = source.AuthorizationPolicy.IsDefined && source.AuthorizationPolicy.Value is { } ap ? FromApi(ap) : null, + SubjectTypeAuthorization = FromApi(source.SubjectTypeAuthorization), + TokenEncryption = source.TokenEncryption.IsDefined && source.TokenEncryption.Value is { } te ? FromApi(te) : null, + ProofOfPossession = source.ProofOfPossession.IsDefined && source.ProofOfPossession.Value is { } pop ? FromApi(pop) : null, }; [return: NotNullIfNotNull(nameof(source))] - internal static V1ResourceServerScope? FromApi(ResourceServerScope? source) => source is null ? null : new() + internal static V1ResourceServerAuthorizationPolicy? FromApi(ResourceServerAuthorizationPolicy? source) => source is null ? null : new() { - Value = source.Value, - Description = source.Description, + PolicyId = source.PolicyId, }; [return: NotNullIfNotNull(nameof(source))] - internal static V1ResourceServerSigningAlgorithm? FromApi(SigningAlgorithm? source) => source switch + internal static V1ResourceServerSubjectTypeAuthorization? FromApi(ResourceServerSubjectTypeAuthorization? source) => source is null ? null : new() { - SigningAlgorithm.HS256 => V1ResourceServerSigningAlgorithm.HS256, - SigningAlgorithm.RS256 => V1ResourceServerSigningAlgorithm.RS256, - SigningAlgorithm.PS256 => V1ResourceServerSigningAlgorithm.PS256, - null => null, - _ => throw new NotImplementedException(), + Client = FromApi(source.Client), + User = FromApi(source.User), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V1ResourceServerSubjectTypeAuthorizationClient? FromApi(ResourceServerSubjectTypeAuthorizationClient? source) => source is null ? null : new() + { + Policy = source.Policy is { } policy ? FromApi(policy) : null, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V1ResourceServerSubjectTypeAuthorizationUser? FromApi(ResourceServerSubjectTypeAuthorizationUser? source) => source is null ? null : new() + { + Policy = source.Policy is { } policy ? FromApi(policy) : null, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V1ResourceServerScope? FromApi(ResourceServerScope? source) => source is null ? null : new() + { + Value = source.Value, + Description = source.Description, }; [return: NotNullIfNotNull(nameof(source))] - internal static V1ResourceServerTokenDialect? FromApi(TokenDialect? source) => source switch + internal static V1ResourceServerSigningAlgorithm? FromApi(SigningAlgorithmEnum? source) => source?.Value switch { - TokenDialect.AccessToken => V1ResourceServerTokenDialect.AccessToken, - TokenDialect.AccessTokenAuthZ => V1ResourceServerTokenDialect.AccessTokenAuthZ, - TokenDialect.Rfc9068Profile => V1ResourceServerTokenDialect.Rfc9068Profile, - TokenDialect.Rfc9068ProfileAuthz => V1ResourceServerTokenDialect.Rfc9068ProfileAuthz, + SigningAlgorithmEnum.Values.Hs256 => V1ResourceServerSigningAlgorithm.HS256, + SigningAlgorithmEnum.Values.Rs256 => V1ResourceServerSigningAlgorithm.RS256, + SigningAlgorithmEnum.Values.Ps256 => V1ResourceServerSigningAlgorithm.PS256, null => null, _ => throw new NotImplementedException(), }; [return: NotNullIfNotNull(nameof(source))] - internal static V1ResourceServerConsentPolicy? FromApi(ConsentPolicy? source) => source switch + internal static V1ResourceServerTokenDialect? FromApi(ResourceServerTokenDialectResponseEnum source) => source.Value switch { - ConsentPolicy.TransactionalAuthorizationWithMfa => V1ResourceServerConsentPolicy.TransactionalAuthorizationWithMfa, - null => null, + ResourceServerTokenDialectResponseEnum.Values.AccessToken => V1ResourceServerTokenDialect.AccessToken, + ResourceServerTokenDialectResponseEnum.Values.AccessTokenAuthz => V1ResourceServerTokenDialect.AccessTokenAuthZ, + ResourceServerTokenDialectResponseEnum.Values.Rfc9068Profile => V1ResourceServerTokenDialect.Rfc9068Profile, + ResourceServerTokenDialectResponseEnum.Values.Rfc9068ProfileAuthz => V1ResourceServerTokenDialect.Rfc9068ProfileAuthz, _ => throw new NotImplementedException(), }; [return: NotNullIfNotNull(nameof(source))] - internal static V1ResourceServerAuthorizationDetail? FromApi(ResourceServerAuthorizationDetail? source) => source is null ? null : new() + internal static V1ResourceServerConsentPolicy? FromApi(ResourceServerConsentPolicyEnum source) => source.Value switch { - Type = source.Type, + ResourceServerConsentPolicyEnum.Values.TransactionalAuthorizationWithMfa => V1ResourceServerConsentPolicy.TransactionalAuthorizationWithMfa, + _ => throw new NotImplementedException(), }; [return: NotNullIfNotNull(nameof(source))] - internal static V1ResourceServerTokenEncryption? FromApi(TokenEncryption? source) => source is null ? null : new() + internal static V1ResourceServerTokenEncryption? FromApi(ResourceServerTokenEncryption? source) => source is null ? null : new() { Format = FromApi(source.Format), EncryptionKey = FromApi(source.EncryptionKey), }; [return: NotNullIfNotNull(nameof(source))] - internal static V1ResourceServerTokenFormat? FromApi(TokenFormat source) => source switch + internal static V1ResourceServerTokenFormat? FromApi(ResourceServerTokenEncryptionFormatEnum source) => source.Value switch { - TokenFormat.CompactNestedJwe => V1ResourceServerTokenFormat.CompactNestedJwe, + ResourceServerTokenEncryptionFormatEnum.Values.CompactNestedJwe => V1ResourceServerTokenFormat.CompactNestedJwe, _ => throw new NotImplementedException(), }; [return: NotNullIfNotNull(nameof(source))] - internal static V1ResourceServerTokenEncryptionKey? FromApi(TokenEncryptionKey? source) => source is null ? null : new() + internal static V1ResourceServerTokenEncryptionKey? FromApi(ResourceServerTokenEncryptionKey? source) => source is null ? null : new() { Name = source.Name, - Algorithm = source.Algorithm, + Algorithm = source.Alg?.Value, Kid = source.Kid, Pem = source.Pem, }; [return: NotNullIfNotNull(nameof(source))] - internal static V1ResourceServerProofOfPossession? FromApi(ProofOfPossession? source) => source is null ? null : new() + internal static V1ResourceServerProofOfPossession? FromApi(ResourceServerProofOfPossession? source) => source is null ? null : new() { Required = source.Required, Mechanism = FromApi(source.Mechanism), }; - internal static V1ResourceServerMechanism? FromApi(Mechanism source) => source switch + internal static V1ResourceServerMechanism? FromApi(ResourceServerProofOfPossessionMechanismEnum source) => source.Value switch + { + ResourceServerProofOfPossessionMechanismEnum.Values.Dpop => V1ResourceServerMechanism.Dpop, + ResourceServerProofOfPossessionMechanismEnum.Values.Mtls => V1ResourceServerMechanism.Mtls, + _ => throw new NotImplementedException(), + }; + + internal static V1ResourceServerSubjectTypeAuthorizationClientPolicy? FromApi(ResourceServerSubjectTypeAuthorizationClientPolicyEnum source) => source.Value switch + { + ResourceServerSubjectTypeAuthorizationClientPolicyEnum.Values.DenyAll => V1ResourceServerSubjectTypeAuthorizationClientPolicy.DenyAll, + ResourceServerSubjectTypeAuthorizationClientPolicyEnum.Values.RequireClientGrant => V1ResourceServerSubjectTypeAuthorizationClientPolicy.RequireClientGrant, + _ => throw new NotImplementedException(), + }; + + internal static V1ResourceServerSubjectTypeAuthorizationUserPolicy? FromApi(ResourceServerSubjectTypeAuthorizationUserPolicyEnum source) => source.Value switch + { + ResourceServerSubjectTypeAuthorizationUserPolicyEnum.Values.AllowAll => V1ResourceServerSubjectTypeAuthorizationUserPolicy.AllowAll, + ResourceServerSubjectTypeAuthorizationUserPolicyEnum.Values.DenyAll => V1ResourceServerSubjectTypeAuthorizationUserPolicy.DenyAll, + ResourceServerSubjectTypeAuthorizationUserPolicyEnum.Values.RequireClientGrant => V1ResourceServerSubjectTypeAuthorizationUserPolicy.RequireClientGrant, + _ => throw new NotImplementedException(), + }; + + internal static SigningAlgorithmEnum ToApi(V1ResourceServerSigningAlgorithm source) => source switch + { + V1ResourceServerSigningAlgorithm.HS256 => new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Hs256), + V1ResourceServerSigningAlgorithm.RS256 => new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Rs256), + V1ResourceServerSigningAlgorithm.PS256 => new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Ps256), + _ => throw new NotImplementedException(), + }; + + internal static ResourceServerTokenDialectSchemaEnum ToApi(V1ResourceServerTokenDialect source) => source switch { - Mechanism.Mtls => V1ResourceServerMechanism.Mtls, + V1ResourceServerTokenDialect.AccessToken => new ResourceServerTokenDialectSchemaEnum(ResourceServerTokenDialectSchemaEnum.Values.AccessToken), + V1ResourceServerTokenDialect.AccessTokenAuthZ => new ResourceServerTokenDialectSchemaEnum(ResourceServerTokenDialectSchemaEnum.Values.AccessTokenAuthz), + V1ResourceServerTokenDialect.Rfc9068Profile => new ResourceServerTokenDialectSchemaEnum(ResourceServerTokenDialectSchemaEnum.Values.Rfc9068Profile), + V1ResourceServerTokenDialect.Rfc9068ProfileAuthz => new ResourceServerTokenDialectSchemaEnum(ResourceServerTokenDialectSchemaEnum.Values.Rfc9068ProfileAuthz), _ => throw new NotImplementedException(), }; - internal static SigningAlgorithm ToApi(V1ResourceServerSigningAlgorithm source) => source switch + internal static ResourceServerConsentPolicyEnum ToApi(V1ResourceServerConsentPolicy source) => source switch { - V1ResourceServerSigningAlgorithm.HS256 => SigningAlgorithm.HS256, - V1ResourceServerSigningAlgorithm.RS256 => SigningAlgorithm.RS256, - V1ResourceServerSigningAlgorithm.PS256 => SigningAlgorithm.PS256, + V1ResourceServerConsentPolicy.TransactionalAuthorizationWithMfa => new ResourceServerConsentPolicyEnum(ResourceServerConsentPolicyEnum.Values.TransactionalAuthorizationWithMfa), _ => throw new NotImplementedException(), }; - internal static TokenDialect ToApi(V1ResourceServerTokenDialect source) => source switch + internal static ResourceServerAuthorizationPolicy ToApi(V1ResourceServerAuthorizationPolicy source) => new() + { + PolicyId = source.PolicyId, + }; + + internal static ResourceServerSubjectTypeAuthorization ToApi(V1ResourceServerSubjectTypeAuthorization source) => new() + { + Client = source.Client is { } client ? ToApi(client) : null, + User = source.User is { } user ? ToApi(user) : null, + }; + + internal static ResourceServerSubjectTypeAuthorizationClient ToApi(V1ResourceServerSubjectTypeAuthorizationClient source) => new() + { + Policy = source.Policy is { } policy ? ToApi(policy) : null, + }; + + internal static ResourceServerSubjectTypeAuthorizationUser ToApi(V1ResourceServerSubjectTypeAuthorizationUser source) => new() { - V1ResourceServerTokenDialect.AccessToken => TokenDialect.AccessToken, - V1ResourceServerTokenDialect.AccessTokenAuthZ => TokenDialect.AccessTokenAuthZ, - V1ResourceServerTokenDialect.Rfc9068Profile => TokenDialect.Rfc9068Profile, - V1ResourceServerTokenDialect.Rfc9068ProfileAuthz => TokenDialect.Rfc9068ProfileAuthz, + Policy = source.Policy is { } policy ? ToApi(policy) : null, + }; + + internal static ResourceServerTokenEncryptionFormatEnum ToApi(V1ResourceServerTokenFormat source) => source switch + { + V1ResourceServerTokenFormat.CompactNestedJwe => new ResourceServerTokenEncryptionFormatEnum(ResourceServerTokenEncryptionFormatEnum.Values.CompactNestedJwe), _ => throw new NotImplementedException(), }; - internal static ConsentPolicy ToApi(V1ResourceServerConsentPolicy source) => source switch + internal static ResourceServerTokenEncryption ToApi(V1ResourceServerTokenEncryption source) => new() + { + Format = ToApi(source.Format ?? default), + EncryptionKey = source.EncryptionKey is { } key ? ToApi(key) : null, + }; + + internal static ResourceServerTokenEncryptionKey ToApi(V1ResourceServerTokenEncryptionKey source) => new() { - V1ResourceServerConsentPolicy.TransactionalAuthorizationWithMfa => ConsentPolicy.TransactionalAuthorizationWithMfa, + Name = source.Name, + Kid = source.Kid, + Pem = source.Pem, + }; + + internal static ResourceServerProofOfPossessionMechanismEnum ToApi(V1ResourceServerMechanism source) => source switch + { + V1ResourceServerMechanism.Dpop => new ResourceServerProofOfPossessionMechanismEnum(ResourceServerProofOfPossessionMechanismEnum.Values.Dpop), + V1ResourceServerMechanism.Mtls => new ResourceServerProofOfPossessionMechanismEnum(ResourceServerProofOfPossessionMechanismEnum.Values.Mtls), _ => throw new NotImplementedException(), }; - internal static TokenFormat ToApi(V1ResourceServerTokenFormat source) => source switch + internal static ResourceServerSubjectTypeAuthorizationClientPolicyEnum ToApi(V1ResourceServerSubjectTypeAuthorizationClientPolicy source) => source switch { - V1ResourceServerTokenFormat.CompactNestedJwe => TokenFormat.CompactNestedJwe, + V1ResourceServerSubjectTypeAuthorizationClientPolicy.DenyAll => new ResourceServerSubjectTypeAuthorizationClientPolicyEnum(ResourceServerSubjectTypeAuthorizationClientPolicyEnum.Values.DenyAll), + V1ResourceServerSubjectTypeAuthorizationClientPolicy.RequireClientGrant => new ResourceServerSubjectTypeAuthorizationClientPolicyEnum(ResourceServerSubjectTypeAuthorizationClientPolicyEnum.Values.RequireClientGrant), _ => throw new NotImplementedException(), }; - internal static Mechanism ToApi(V1ResourceServerMechanism source) => source switch + internal static ResourceServerSubjectTypeAuthorizationUserPolicyEnum ToApi(V1ResourceServerSubjectTypeAuthorizationUserPolicy source) => source switch { - V1ResourceServerMechanism.Mtls => Mechanism.Mtls, + V1ResourceServerSubjectTypeAuthorizationUserPolicy.AllowAll => new ResourceServerSubjectTypeAuthorizationUserPolicyEnum(ResourceServerSubjectTypeAuthorizationUserPolicyEnum.Values.AllowAll), + V1ResourceServerSubjectTypeAuthorizationUserPolicy.DenyAll => new ResourceServerSubjectTypeAuthorizationUserPolicyEnum(ResourceServerSubjectTypeAuthorizationUserPolicyEnum.Values.DenyAll), + V1ResourceServerSubjectTypeAuthorizationUserPolicy.RequireClientGrant => new ResourceServerSubjectTypeAuthorizationUserPolicyEnum(ResourceServerSubjectTypeAuthorizationUserPolicyEnum.Values.RequireClientGrant), _ => throw new NotImplementedException(), }; + internal static ResourceServerProofOfPossession ToApi(V1ResourceServerProofOfPossession source) => new() + { + Required = source.Required ?? false, + Mechanism = source.Mechanism is { } mech ? ToApi(mech) : default!, + }; + internal static ResourceServerScope ToApi(V1ResourceServerScope source) => new() { Value = source.Value, Description = source.Description, }; - internal static ResourceServerAuthorizationDetail ToApi(V1ResourceServerAuthorizationDetail source) => new() + internal static void ApplyToApi(V1ResourceServerConf conf, CreateResourceServerRequestContent request) { - Type = source.Type, - }; + if (conf.Identifier is not null) + request.Identifier = conf.Identifier; - internal static void ApplyToApi(V1ResourceServerConf conf, ResourceServerBase request) - { if (conf.Name is not null) request.Name = conf.Name; if (conf.Scopes is not null) request.Scopes = conf.Scopes.Select(ToApi).ToList(); - if (conf.SigningAlgorithm is { } signing_alg) - request.SigningAlgorithm = ToApi(signing_alg); + if (conf.SigningAlgorithm is { } signingAlg) + request.SigningAlg = ToApi(signingAlg); if (conf.SigningSecret is not null) request.SigningSecret = conf.SigningSecret; @@ -202,66 +314,89 @@ internal static void ApplyToApi(V1ResourceServerConf conf, ResourceServerBase re if (conf.TokenLifetime is not null) request.TokenLifetime = conf.TokenLifetime; - if (conf.TokenLifetimeForWeb is not null) - request.TokenLifetimeForWeb = conf.TokenLifetimeForWeb; - if (conf.AllowOfflineAccess is not null) request.AllowOfflineAccess = conf.AllowOfflineAccess; + if (conf.AllowOnlineAccess is not null) + request.AllowOnlineAccess = conf.AllowOnlineAccess; + + if (conf.AllowOnlineAccessWithEphemeralSessions is not null) + request.AllowOnlineAccessWithEphemeralSessions = conf.AllowOnlineAccessWithEphemeralSessions; + if (conf.SkipConsentForVerifiableFirstPartyClients is not null) request.SkipConsentForVerifiableFirstPartyClients = conf.SkipConsentForVerifiableFirstPartyClients; - if (conf.VerificationLocation is not null) - request.VerificationLocation = conf.VerificationLocation; - - if (conf.TokenDialect is { } token_dialect) - request.TokenDialect = ToApi(token_dialect); + if (conf.TokenDialect is { } tokenDialect) + request.TokenDialect = ToApi(tokenDialect); if (conf.EnforcePolicies is not null) request.EnforcePolicies = conf.EnforcePolicies; - if (conf.ConsentPolicy is { } consent_policy) - request.ConsentPolicy = ToApi(consent_policy); + if (conf.ConsentPolicy is { } consentPolicy) + request.ConsentPolicy = ToApi(consentPolicy); - if (conf.AuthorizationDetails is not null) - request.AuthorizationDetails = conf.AuthorizationDetails.Select(ToApi).ToList(); + if (conf.AuthorizationPolicy is { } authorizationPolicy) + request.AuthorizationPolicy = ToApi(authorizationPolicy); - if (conf.TokenEncryption is { } token_encryption) - { - request.TokenEncryption = new TokenEncryption - { - Format = ToApi(token_encryption.Format ?? default), - EncryptionKey = token_encryption.EncryptionKey is { } key ? new TokenEncryptionKey - { - Name = key.Name, - Algorithm = key.Algorithm, - Kid = key.Kid, - Pem = key.Pem, - } : null, - }; - } + if (conf.SubjectTypeAuthorization is { } subjectTypeAuthorization) + request.SubjectTypeAuthorization = ToApi(subjectTypeAuthorization); + + if (conf.TokenEncryption is { } tokenEncryption) + request.TokenEncryption = ToApi(tokenEncryption); if (conf.ProofOfPossession is { } pop) - { - request.ProofOfPossession = new ProofOfPossession - { - Required = pop.Required, - Mechanism = pop.Mechanism is { } mech ? ToApi(mech) : default, - }; - } + request.ProofOfPossession = ToApi(pop); } - internal static void ApplyToApi(V1ResourceServerConf conf, ResourceServerCreateRequest request) + internal static void ApplyToApi(V1ResourceServerConf conf, UpdateResourceServerRequestContent request) { - if (conf.Identifier is not null) - request.Identifier = conf.Identifier; + if (conf.Name is not null) + request.Name = conf.Name; - ApplyToApi(conf, (ResourceServerBase)request); - } + if (conf.Scopes is not null) + request.Scopes = conf.Scopes.Select(ToApi).ToList(); - internal static void ApplyToApi(V1ResourceServerConf conf, ResourceServerUpdateRequest request) - { - ApplyToApi(conf, (ResourceServerBase)request); + if (conf.SigningAlgorithm is { } signingAlg) + request.SigningAlg = ToApi(signingAlg); + + if (conf.SigningSecret is not null) + request.SigningSecret = conf.SigningSecret; + + if (conf.TokenLifetime is not null) + request.TokenLifetime = conf.TokenLifetime; + + if (conf.AllowOfflineAccess is not null) + request.AllowOfflineAccess = conf.AllowOfflineAccess; + + if (conf.AllowOnlineAccess is not null) + request.AllowOnlineAccess = conf.AllowOnlineAccess; + + if (conf.AllowOnlineAccessWithEphemeralSessions is not null) + request.AllowOnlineAccessWithEphemeralSessions = conf.AllowOnlineAccessWithEphemeralSessions; + + if (conf.SkipConsentForVerifiableFirstPartyClients is not null) + request.SkipConsentForVerifiableFirstPartyClients = conf.SkipConsentForVerifiableFirstPartyClients; + + if (conf.TokenDialect is { } tokenDialect) + request.TokenDialect = ToApi(tokenDialect); + + if (conf.EnforcePolicies is not null) + request.EnforcePolicies = conf.EnforcePolicies; + + if (conf.ConsentPolicy is { } consentPolicy) + request.ConsentPolicy = ToApi(consentPolicy); + + if (conf.AuthorizationPolicy is { } authorizationPolicy) + request.AuthorizationPolicy = ToApi(authorizationPolicy); + + if (conf.SubjectTypeAuthorization is { } subjectTypeAuthorization) + request.SubjectTypeAuthorization = ToApi(subjectTypeAuthorization); + + if (conf.TokenEncryption is { } tokenEncryption) + request.TokenEncryption = ToApi(tokenEncryption); + + if (conf.ProofOfPossession is { } pop) + request.ProofOfPossession = ToApi(pop); } /// @@ -285,7 +420,7 @@ public V1ResourceServerController(IKubernetesClient kube, IMemoryCache cache, IO { try { - return FromApi(await api.ResourceServers.GetAsync(id, cancellationToken: cancellationToken)); + return FromApi(await api.ResourceServers.GetAsync(id, new GetResourceServerRequestParameters(), null, cancellationToken)); } catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) { @@ -300,8 +435,8 @@ public V1ResourceServerController(IKubernetesClient kube, IMemoryCache cache, IO if (conf is null) return null; - var list = await api.ResourceServers.GetAllAsync(new ResourceServerGetRequest() { }, cancellationToken: cancellationToken); - var self = list.FirstOrDefault(i => i.Identifier == conf.Identifier); + var pager = await api.ResourceServers.ListAsync(new ListResourceServerRequestParameters(), null, cancellationToken); + var self = pager.CurrentPage.Items?.FirstOrDefault(i => i.Identifier == conf.Identifier); return self?.Id; } @@ -314,18 +449,18 @@ public V1ResourceServerController(IKubernetesClient kube, IMemoryCache cache, IO /// protected override async Task Create(IManagementApiClient api, V1ResourceServerConf conf, string defaultNamespace, CancellationToken cancellationToken) { - var req = new ResourceServerCreateRequest(); + var req = new CreateResourceServerRequestContent { Identifier = conf.Identifier ?? throw new InvalidOperationException("Identifier is required.") }; ApplyToApi(conf, req); - var self = await api.ResourceServers.CreateAsync(req, cancellationToken); + var self = await api.ResourceServers.CreateAsync(req, null, cancellationToken); return self.Id; } /// protected override async Task Update(IManagementApiClient api, string id, V1ResourceServerConf? last, V1ResourceServerConf conf, string defaultNamespace, CancellationToken cancellationToken) { - var req = new ResourceServerUpdateRequest(); + var req = new UpdateResourceServerRequestContent(); ApplyToApi(conf, req); - await api.ResourceServers.UpdateAsync(id, req, cancellationToken); + await api.ResourceServers.UpdateAsync(id, req, null, cancellationToken); } /// @@ -341,7 +476,7 @@ protected override Task ApplyStatus(IManagementApiClient api, V1ResourceServer e /// protected override Task DeletedAsync(IManagementApiClient api, string id, CancellationToken cancellationToken) { - return api.ResourceServers.DeleteAsync(id, cancellationToken); + return api.ResourceServers.DeleteAsync(id, null, cancellationToken); } } diff --git a/src/Alethic.Auth0.Operator/Controllers/V1alpha1BrandingThemeController.cs b/src/Alethic.Auth0.Operator/Controllers/V1alpha1BrandingThemeController.cs index d4106ba..e293a98 100644 --- a/src/Alethic.Auth0.Operator/Controllers/V1alpha1BrandingThemeController.cs +++ b/src/Alethic.Auth0.Operator/Controllers/V1alpha1BrandingThemeController.cs @@ -9,7 +9,7 @@ using Auth0.Core.Exceptions; using Auth0.ManagementApi; -using Auth0.ManagementApi.Models; +using Auth0.ManagementApi.Branding; using k8s.Models; @@ -39,11 +39,11 @@ public class V1alpha1BrandingThemeController : /// /// /// - internal static CaptchaWidgetTheme ToApi(V1alpha1BrandingThemeCaptchaWidgetTheme source) => source switch + internal static BrandingThemeColorsCaptchaWidgetThemeEnum ToApi(V1alpha1BrandingThemeCaptchaWidgetTheme source) => source switch { - V1alpha1BrandingThemeCaptchaWidgetTheme.Light => CaptchaWidgetTheme.Light, - V1alpha1BrandingThemeCaptchaWidgetTheme.Dark => CaptchaWidgetTheme.Dark, - V1alpha1BrandingThemeCaptchaWidgetTheme.Auto => CaptchaWidgetTheme.Auto, + V1alpha1BrandingThemeCaptchaWidgetTheme.Light => new BrandingThemeColorsCaptchaWidgetThemeEnum(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Light), + V1alpha1BrandingThemeCaptchaWidgetTheme.Dark => new BrandingThemeColorsCaptchaWidgetThemeEnum(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Dark), + V1alpha1BrandingThemeCaptchaWidgetTheme.Auto => new BrandingThemeColorsCaptchaWidgetThemeEnum(BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Auto), _ => throw new InvalidOperationException() }; @@ -53,10 +53,11 @@ public class V1alpha1BrandingThemeController : /// /// /// - internal static LinksStyle ToApi(V1alpha1BrandingThemeFonts source) => source.LinksStyle switch + internal static BrandingThemeFontLinksStyleEnum ToApiLinksStyle(V1alpha1BrandingThemeLinksStyle? source) => source switch { - V1alpha1BrandingThemeLinksStyle.Normal => LinksStyle.Normal, - V1alpha1BrandingThemeLinksStyle.Underlined => LinksStyle.Underlined, + V1alpha1BrandingThemeLinksStyle.Normal => new BrandingThemeFontLinksStyleEnum(BrandingThemeFontLinksStyleEnum.Values.Normal), + V1alpha1BrandingThemeLinksStyle.Underlined => new BrandingThemeFontLinksStyleEnum(BrandingThemeFontLinksStyleEnum.Values.Underlined), + null => new BrandingThemeFontLinksStyleEnum(BrandingThemeFontLinksStyleEnum.Values.Normal), _ => throw new InvalidOperationException() }; @@ -66,10 +67,10 @@ public class V1alpha1BrandingThemeController : /// /// /// - internal static SocialButtonsLayout ToApi(V1alpha1BrandingThemeSocialButtonsLayout source) => source switch + internal static BrandingThemeWidgetSocialButtonsLayoutEnum ToApi(V1alpha1BrandingThemeSocialButtonsLayout source) => source switch { - V1alpha1BrandingThemeSocialButtonsLayout.Top => SocialButtonsLayout.Top, - V1alpha1BrandingThemeSocialButtonsLayout.Bottom => SocialButtonsLayout.Bottom, + V1alpha1BrandingThemeSocialButtonsLayout.Top => new BrandingThemeWidgetSocialButtonsLayoutEnum(BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Top), + V1alpha1BrandingThemeSocialButtonsLayout.Bottom => new BrandingThemeWidgetSocialButtonsLayoutEnum(BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Bottom), _ => throw new InvalidOperationException() }; @@ -79,12 +80,12 @@ public class V1alpha1BrandingThemeController : /// /// /// - internal static LogoPosition ToApi(V1alpha1BrandingThemeLogoPosition source) => source switch + internal static BrandingThemeWidgetLogoPositionEnum ToApi(V1alpha1BrandingThemeLogoPosition source) => source switch { - V1alpha1BrandingThemeLogoPosition.Center => LogoPosition.Center, - V1alpha1BrandingThemeLogoPosition.Left => LogoPosition.Left, - V1alpha1BrandingThemeLogoPosition.Right => LogoPosition.Right, - V1alpha1BrandingThemeLogoPosition.None => LogoPosition.None, + V1alpha1BrandingThemeLogoPosition.Center => new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.Center), + V1alpha1BrandingThemeLogoPosition.Left => new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.Left), + V1alpha1BrandingThemeLogoPosition.Right => new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.Right), + V1alpha1BrandingThemeLogoPosition.None => new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.None), _ => throw new InvalidOperationException() }; @@ -94,11 +95,11 @@ public class V1alpha1BrandingThemeController : /// /// /// - internal static HeaderTextAlignment ToApi(V1alpha1BrandingThemeHeaderTextAlignment source) => source switch + internal static BrandingThemeWidgetHeaderTextAlignmentEnum ToApi(V1alpha1BrandingThemeHeaderTextAlignment source) => source switch { - V1alpha1BrandingThemeHeaderTextAlignment.Center => HeaderTextAlignment.Center, - V1alpha1BrandingThemeHeaderTextAlignment.Left => HeaderTextAlignment.Left, - V1alpha1BrandingThemeHeaderTextAlignment.Right => HeaderTextAlignment.Right, + V1alpha1BrandingThemeHeaderTextAlignment.Center => new BrandingThemeWidgetHeaderTextAlignmentEnum(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Center), + V1alpha1BrandingThemeHeaderTextAlignment.Left => new BrandingThemeWidgetHeaderTextAlignmentEnum(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Left), + V1alpha1BrandingThemeHeaderTextAlignment.Right => new BrandingThemeWidgetHeaderTextAlignmentEnum(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Right), _ => throw new InvalidOperationException() }; @@ -108,11 +109,11 @@ public class V1alpha1BrandingThemeController : /// /// /// - internal static PageLayout ToApi(V1alpha1BrandingThemePageLayout source) => source switch + internal static BrandingThemePageBackgroundPageLayoutEnum ToApi(V1alpha1BrandingThemePageLayout source) => source switch { - V1alpha1BrandingThemePageLayout.Right => PageLayout.Right, - V1alpha1BrandingThemePageLayout.Center => PageLayout.Center, - V1alpha1BrandingThemePageLayout.Left => PageLayout.Left, + V1alpha1BrandingThemePageLayout.Right => new BrandingThemePageBackgroundPageLayoutEnum(BrandingThemePageBackgroundPageLayoutEnum.Values.Right), + V1alpha1BrandingThemePageLayout.Center => new BrandingThemePageBackgroundPageLayoutEnum(BrandingThemePageBackgroundPageLayoutEnum.Values.Center), + V1alpha1BrandingThemePageLayout.Left => new BrandingThemePageBackgroundPageLayoutEnum(BrandingThemePageBackgroundPageLayoutEnum.Values.Left), _ => throw new InvalidOperationException() }; @@ -122,257 +123,195 @@ public class V1alpha1BrandingThemeController : /// /// /// - internal static ButtonsStyle ToApi(V1alpha1BrandingThemeButtonsStyle buttonsStyle) => buttonsStyle switch + internal static BrandingThemeBordersButtonsStyleEnum ToApiButtonsStyle(V1alpha1BrandingThemeButtonsStyle buttonsStyle) => buttonsStyle switch { - V1alpha1BrandingThemeButtonsStyle.Pill => ButtonsStyle.Pill, - V1alpha1BrandingThemeButtonsStyle.Rounded => ButtonsStyle.Rounded, - V1alpha1BrandingThemeButtonsStyle.Sharp => ButtonsStyle.Sharp, + V1alpha1BrandingThemeButtonsStyle.Pill => new BrandingThemeBordersButtonsStyleEnum(BrandingThemeBordersButtonsStyleEnum.Values.Pill), + V1alpha1BrandingThemeButtonsStyle.Rounded => new BrandingThemeBordersButtonsStyleEnum(BrandingThemeBordersButtonsStyleEnum.Values.Rounded), + V1alpha1BrandingThemeButtonsStyle.Sharp => new BrandingThemeBordersButtonsStyleEnum(BrandingThemeBordersButtonsStyleEnum.Values.Sharp), _ => throw new InvalidOperationException() }; /// - /// Applies the specified configuration to the target. + /// Transforms the specified source to the API type. /// - /// - /// - internal static void ApplyToApi(V1alpha1BrandingThemeConf? source, BrandingThemeBase target) + /// + /// + /// + internal static BrandingThemeBordersInputsStyleEnum ToApiInputsStyle(V1alpha1BrandingThemeButtonsStyle inputsStyle) => inputsStyle switch { - if (source is null) - return; - - if (source.DisplayName is not null) - target.DisplayName = source.DisplayName; - - if (source.Borders is not null) - ApplyToApi(source.Borders, target.Borders = new BrandingThemeBorder()); - - if (source.Colors is not null) - ApplyToApi(source.Colors, target.Colors = new BrandingThemeColors()); - - if (source.Fonts is not null) - ApplyToApi(source.Fonts, target.Fonts = new BrandingThemeFonts()); - - if (source.Widget is not null) - ApplyToApi(source.Widget, target.Widget = new BrandingThemeWidget()); - - if (source.PageBackground is not null) - ApplyToApi(source.PageBackground, target.PageBackground = new BrandingThemePageBackground()); - } + V1alpha1BrandingThemeButtonsStyle.Pill => new BrandingThemeBordersInputsStyleEnum(BrandingThemeBordersInputsStyleEnum.Values.Pill), + V1alpha1BrandingThemeButtonsStyle.Rounded => new BrandingThemeBordersInputsStyleEnum(BrandingThemeBordersInputsStyleEnum.Values.Rounded), + V1alpha1BrandingThemeButtonsStyle.Sharp => new BrandingThemeBordersInputsStyleEnum(BrandingThemeBordersInputsStyleEnum.Values.Sharp), + _ => throw new InvalidOperationException() + }; /// - /// Applies the specified configuration to the target. + /// Converts the specified configuration to a new . /// - /// - /// - /// - internal static void ApplyToApi(V1alpha1BrandingThemeBorders? source, BrandingThemeBorder target) + internal static BrandingThemeFontBodyText ToApi(V1alpha1BrandingThemeFont? source, BrandingThemeFontBodyText? existing = null) => new() { - if (source is null) - return; - - if (source.ButtonBorderRadius is float buttonBorderRadius) - target.ButtonBorderRadius = buttonBorderRadius; - - if (source.ButtonBorderWeight is float buttonBorderWeight) - target.ButtonBorderWeight = buttonBorderWeight; - - if (source.ButtonsStyle is V1alpha1BrandingThemeButtonsStyle buttonsStyle) - target.ButtonsStyle = ToApi(buttonsStyle); - - if (source.InputBorderRadius is float inputBorderRadius) - target.InputBorderRadius = inputBorderRadius; - - if (source.InputBorderWeight is float inputBorderWeight) - target.InputBorderWeight = inputBorderWeight; - - if (source.InputsStyle is V1alpha1BrandingThemeButtonsStyle inputsStyle) - target.InputsStyle = ToApi(inputsStyle); - - if (source.ShowWidgetShadow is bool showWidgetShadow) - target.ShowWidgetShadow = showWidgetShadow; - - if (source.WidgetBorderWeight is float widgetBorderWeight) - target.WidgetBorderWeight = widgetBorderWeight; - - if (source.WidgetCornerRadius is float widgetCornerRadius) - target.WidgetCornerRadius = widgetCornerRadius; - } + Bold = source?.Bold ?? existing?.Bold ?? false, + Size = source?.Size ?? (existing?.Size is double es ? (float)es : 0f), + }; /// - /// Applies the specified configuration to the target. + /// Converts the specified configuration to a new . /// - /// - /// - internal static void ApplyToApi(V1alpha1BrandingThemeColors? source, BrandingThemeColors target) + internal static BrandingThemeFontButtonsText ToApi(V1alpha1BrandingThemeFont? source, BrandingThemeFontButtonsText? existing = null) => new() { - if (source is null) - return; - - if (source.BaseFocusColor is string baseFocusColor) - target.BaseFocusColor = baseFocusColor; - - if (source.BaseHoverColor is string baseHoverColor) - target.BaseHoverColor = baseHoverColor; - - if (source.BodyText is string bodyText) - target.BodyText = bodyText; - - if (source.CaptchaWidgetTheme is V1alpha1BrandingThemeCaptchaWidgetTheme captchaWidgetTheme) - target.CaptchaWidgetTheme = ToApi(captchaWidgetTheme); - - if (source.Error is string error) - target.Error = error; - - if (source.Header is string header) - target.Header = header; - - if (source.Icons is string icons) - target.Icons = icons; - - if (source.InputBackground is string inputBackground) - target.InputBackground = inputBackground; - - if (source.InputBorder is string inputBorder) - target.InputBorder = inputBorder; - - if (source.InputFilledText is string inputFilledText) - target.InputFilledText = inputFilledText; - - if (source.InputLabelsPlaceholders is string inputLabelsPlaceholders) - target.InputLabelsPlaceholders = inputLabelsPlaceholders; - - if (source.LinksFocusedComponents is string linksFocusedComponents) - target.LinksFocusedComponents = linksFocusedComponents; - - if (source.PrimaryButton is string primaryButton) - target.PrimaryButton = primaryButton; - - if (source.PrimaryButtonLabel is string primaryButtonLabel) - target.PrimaryButtonLabel = primaryButtonLabel; - - if (source.SecondaryButtonBorder is string secondaryButtonBorder) - target.SecondaryButtonBorder = secondaryButtonBorder; - - if (source.SecondaryButtonLabel is string secondaryButtonLabel) - target.SecondaryButtonLabel = secondaryButtonLabel; - - if (source.Success is string success) - target.Success = success; - - if (source.WidgetBackground is string widgetBackground) - target.WidgetBackground = widgetBackground; - - if (source.WidgetBorder is string widgetBorder) - target.WidgetBorder = widgetBorder; - } + Bold = source?.Bold ?? existing?.Bold ?? false, + Size = source?.Size ?? (existing?.Size is double es ? (float)es : 0f), + }; /// - /// Applies the specified configuration to the target. + /// Converts the specified configuration to a new . /// - /// - /// - internal static void ApplyToApi(V1alpha1BrandingThemeFonts? source, BrandingThemeFonts target) + internal static BrandingThemeFontInputLabels ToApi(V1alpha1BrandingThemeFont? source, BrandingThemeFontInputLabels? existing = null) => new() { - if (source is null) - return; - - if (source.BodyText is not null) - ApplyToApi(source.BodyText, target.BodyText = new BodyText()); - - if (source.ButtonsText is not null) - ApplyToApi(source.ButtonsText, target.ButtonsText = new ButtonsText()); - - if (source.FontUrl is not null) - target.FontUrl = source.FontUrl; - - if (source.InputLabels is not null) - ApplyToApi(source.InputLabels, target.InputLabels = new InputLabels()); - - if (source.Links is not null) - ApplyToApi(source.Links, target.Links = new Links()); - - if (source.LinksStyle is not null) - target.LinksStyle = ToApi(source); - - if (source.ReferenceTextSize is float referenceTextSize) - target.ReferenceTextSize = referenceTextSize; - - if (source.Subtitle is not null) - ApplyToApi(source.Subtitle, target.Subtitle = new Subtitle()); - - if (source.Title is not null) - ApplyToApi(source.Title, target.Title = new Title()); - } + Bold = source?.Bold ?? existing?.Bold ?? false, + Size = source?.Size ?? (existing?.Size is double es ? (float)es : 0f), + }; /// - /// Applies the specified configuration to the target. + /// Converts the specified configuration to a new . /// - /// - /// - internal static void ApplyToApi(V1alpha1BrandingThemeFont? source, BrandingThemeFontsBase target) + internal static BrandingThemeFontLinks ToApi(V1alpha1BrandingThemeFont? source, BrandingThemeFontLinks? existing = null) => new() { - if (source is null) - return; - - if (source.Bold is bool bold) - target.Bold = bold; - - if (source.Size is float size) - target.Size = size; - } + Bold = source?.Bold ?? existing?.Bold ?? false, + Size = source?.Size ?? (existing?.Size is double es ? (float)es : 0f), + }; /// - /// Applies the specified configuration to the target. + /// Converts the specified configuration to a new . /// - /// - /// - internal static void ApplyToApi(V1alpha1BrandingThemeWidget? source, BrandingThemeWidget target) + internal static BrandingThemeFontSubtitle ToApi(V1alpha1BrandingThemeFont? source, BrandingThemeFontSubtitle? existing = null) => new() { - if (source is null) - return; - - if (source.HeaderTextAlignment is V1alpha1BrandingThemeHeaderTextAlignment headerTextAlignment) - target.HeaderTextAlignment = ToApi(headerTextAlignment); + Bold = source?.Bold ?? existing?.Bold ?? false, + Size = source?.Size ?? (existing?.Size is double es ? (float)es : 0f), + }; - if (source.LogoHeight is float logoHeight) - target.LogoHeight = logoHeight; + /// + /// Converts the specified configuration to a new . + /// + internal static BrandingThemeFontTitle ToApi(V1alpha1BrandingThemeFont? source, BrandingThemeFontTitle? existing = null) => new() + { + Bold = source?.Bold ?? existing?.Bold ?? false, + Size = source?.Size ?? (existing?.Size is double es ? (float)es : 0f), + }; - if (source.LogoPosition is V1alpha1BrandingThemeLogoPosition logoPosition) - target.LogoPosition = ToApi(logoPosition); + /// + /// Converts the specified configuration to a new . + /// + internal static BrandingThemeBorders ToApi(V1alpha1BrandingThemeBorders? source, BrandingThemeBorders? existing = null) => new() + { + ButtonBorderRadius = source?.ButtonBorderRadius ?? (existing?.ButtonBorderRadius is double ebr ? (float)ebr : 0f), + ButtonBorderWeight = source?.ButtonBorderWeight ?? (existing?.ButtonBorderWeight is double ebw ? (float)ebw : 0f), + ButtonsStyle = source?.ButtonsStyle is { } bs ? ToApiButtonsStyle(bs) : existing?.ButtonsStyle ?? new BrandingThemeBordersButtonsStyleEnum(BrandingThemeBordersButtonsStyleEnum.Values.Rounded), + InputBorderRadius = source?.InputBorderRadius ?? (existing?.InputBorderRadius is double eibr ? (float)eibr : 0f), + InputBorderWeight = source?.InputBorderWeight ?? (existing?.InputBorderWeight is double eibw ? (float)eibw : 0f), + InputsStyle = source?.InputsStyle is { } iss ? ToApiInputsStyle(iss) : existing?.InputsStyle ?? new BrandingThemeBordersInputsStyleEnum(BrandingThemeBordersInputsStyleEnum.Values.Rounded), + ShowWidgetShadow = source?.ShowWidgetShadow ?? existing?.ShowWidgetShadow ?? false, + WidgetBorderWeight = source?.WidgetBorderWeight ?? (existing?.WidgetBorderWeight is double ewbw ? (float)ewbw : 0f), + WidgetCornerRadius = source?.WidgetCornerRadius ?? (existing?.WidgetCornerRadius is double ewcr ? (float)ewcr : 0f), + }; - if (source.LogoUrl is string logoUrl) - target.LogoUrl = logoUrl; + /// + /// Converts the specified configuration to a new . + /// + internal static BrandingThemeColors ToApi(V1alpha1BrandingThemeColors? source, BrandingThemeColors? existing = null) => new() + { + BaseFocusColor = source?.BaseFocusColor ?? existing?.BaseFocusColor ?? string.Empty, + BaseHoverColor = source?.BaseHoverColor ?? existing?.BaseHoverColor ?? string.Empty, + BodyText = source?.BodyText ?? existing?.BodyText ?? string.Empty, + CaptchaWidgetTheme = source?.CaptchaWidgetTheme is { } cwt ? ToApi(cwt) : existing?.CaptchaWidgetTheme, + Error = source?.Error ?? existing?.Error ?? string.Empty, + Header = source?.Header ?? existing?.Header ?? string.Empty, + Icons = source?.Icons ?? existing?.Icons ?? string.Empty, + InputBackground = source?.InputBackground ?? existing?.InputBackground ?? string.Empty, + InputBorder = source?.InputBorder ?? existing?.InputBorder ?? string.Empty, + InputFilledText = source?.InputFilledText ?? existing?.InputFilledText ?? string.Empty, + InputLabelsPlaceholders = source?.InputLabelsPlaceholders ?? existing?.InputLabelsPlaceholders ?? string.Empty, + LinksFocusedComponents = source?.LinksFocusedComponents ?? existing?.LinksFocusedComponents ?? string.Empty, + PrimaryButton = source?.PrimaryButton ?? existing?.PrimaryButton ?? string.Empty, + PrimaryButtonLabel = source?.PrimaryButtonLabel ?? existing?.PrimaryButtonLabel ?? string.Empty, + SecondaryButtonBorder = source?.SecondaryButtonBorder ?? existing?.SecondaryButtonBorder ?? string.Empty, + SecondaryButtonLabel = source?.SecondaryButtonLabel ?? existing?.SecondaryButtonLabel ?? string.Empty, + Success = source?.Success ?? existing?.Success ?? string.Empty, + WidgetBackground = source?.WidgetBackground ?? existing?.WidgetBackground ?? string.Empty, + WidgetBorder = source?.WidgetBorder ?? existing?.WidgetBorder ?? string.Empty, + }; - if (source.SocialButtonsLayout is V1alpha1BrandingThemeSocialButtonsLayout socialButtonsLayout) - target.SocialButtonsLayout = ToApi(socialButtonsLayout); - } + /// + /// Converts the specified configuration to a new . + /// + internal static BrandingThemeFonts ToApi(V1alpha1BrandingThemeFonts? source, BrandingThemeFonts? existing = null) => new() + { + BodyText = ToApi(source?.BodyText, existing?.BodyText), + ButtonsText = ToApi(source?.ButtonsText, existing?.ButtonsText), + FontUrl = source?.FontUrl ?? existing?.FontUrl ?? string.Empty, + InputLabels = ToApi(source?.InputLabels, existing?.InputLabels), + Links = ToApi(source?.Links, existing?.Links), + LinksStyle = source?.LinksStyle is { } ls ? ToApiLinksStyle(ls) : existing?.LinksStyle ?? new BrandingThemeFontLinksStyleEnum(BrandingThemeFontLinksStyleEnum.Values.Normal), + ReferenceTextSize = source?.ReferenceTextSize ?? (existing?.ReferenceTextSize is double ers ? (float)ers : 0f), + Subtitle = ToApi(source?.Subtitle, existing?.Subtitle), + Title = ToApi(source?.Title, existing?.Title), + }; /// - /// Applies the specified configuration to the target. + /// Converts the specified configuration to a new . /// - /// - /// - internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, BrandingThemePageBackground target) + internal static BrandingThemeWidget ToApi(V1alpha1BrandingThemeWidget? source, BrandingThemeWidget? existing = null) => new() { - if (source is null) - return; + HeaderTextAlignment = source?.HeaderTextAlignment is { } hta ? ToApi(hta) : existing?.HeaderTextAlignment ?? new BrandingThemeWidgetHeaderTextAlignmentEnum(BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Center), + LogoHeight = source?.LogoHeight ?? (existing?.LogoHeight is double elh ? (float)elh : 0f), + LogoPosition = source?.LogoPosition is { } lp ? ToApi(lp) : existing?.LogoPosition ?? new BrandingThemeWidgetLogoPositionEnum(BrandingThemeWidgetLogoPositionEnum.Values.Center), + LogoUrl = source?.LogoUrl ?? existing?.LogoUrl ?? string.Empty, + SocialButtonsLayout = source?.SocialButtonsLayout is { } sbl ? ToApi(sbl) : existing?.SocialButtonsLayout ?? new BrandingThemeWidgetSocialButtonsLayoutEnum(BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Bottom), + }; - if (source.BackgroundColor is string backgroundColor) - target.BackgroundColor = backgroundColor; + /// + /// Converts the specified configuration to a new . + /// + internal static BrandingThemePageBackground ToApi(V1alpha1BrandingThemePageBackground? source, BrandingThemePageBackground? existing = null) => new() + { + BackgroundColor = source?.BackgroundColor ?? existing?.BackgroundColor ?? string.Empty, + BackgroundImageUrl = source?.BackgroundImageUrl ?? existing?.BackgroundImageUrl ?? string.Empty, + PageLayout = source?.PageLayout is { } pl ? ToApi(pl) : existing?.PageLayout ?? new BrandingThemePageBackgroundPageLayoutEnum(BrandingThemePageBackgroundPageLayoutEnum.Values.Center), + }; - if (source.BackgroundImageUrl is string backgroundImageUrl) - target.BackgroundImageUrl = backgroundImageUrl; + /// + /// Converts the specified configuration to a new . + /// + internal static CreateBrandingThemeRequestContent ToCreateRequest(V1alpha1BrandingThemeConf conf) => new() + { + DisplayName = conf.DisplayName, + Borders = ToApi(conf.Borders), + Colors = ToApi(conf.Colors), + Fonts = ToApi(conf.Fonts), + Widget = ToApi(conf.Widget), + PageBackground = ToApi(conf.PageBackground), + }; - if (source.PageLayout is V1alpha1BrandingThemePageLayout pageLayout) - target.PageLayout = ToApi(pageLayout); - } + /// + /// Converts the specified configuration to a new , + /// layering over so unmanaged fields are preserved. + /// + internal static UpdateBrandingThemeRequestContent ToUpdateRequest(V1alpha1BrandingThemeConf conf, GetBrandingThemeResponseContent existing) => new() + { + DisplayName = conf.DisplayName ?? existing?.DisplayName, + Borders = ToApi(conf.Borders, existing?.Borders), + Colors = ToApi(conf.Colors, existing?.Colors), + Fonts = ToApi(conf.Fonts, existing?.Fonts), + Widget = ToApi(conf.Widget, existing?.Widget), + PageBackground = ToApi(conf.PageBackground, existing?.PageBackground), + }; /// /// Transforms the specified source from the API type. /// /// /// - internal static V1alpha1BrandingThemeConf FromApi(BrandingTheme source) => new() + internal static V1alpha1BrandingThemeConf FromApi(GetBrandingThemeResponseContent source) => new() { DisplayName = source.DisplayName, Borders = FromApi(source.Borders), @@ -387,10 +326,10 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeWidget FromApi(BrandingThemeWidget source) => new() + internal static V1alpha1BrandingThemeWidget? FromApi(BrandingThemeWidget? source) => source is null ? null : new() { HeaderTextAlignment = FromApi(source.HeaderTextAlignment), - LogoHeight = source.LogoHeight, + LogoHeight = (float)source.LogoHeight, LogoPosition = FromApi(source.LogoPosition), LogoUrl = source.LogoUrl, SocialButtonsLayout = FromApi(source.SocialButtonsLayout) @@ -402,10 +341,10 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeSocialButtonsLayout? FromApi(SocialButtonsLayout source) => source switch + internal static V1alpha1BrandingThemeSocialButtonsLayout? FromApi(BrandingThemeWidgetSocialButtonsLayoutEnum source) => source.Value switch { - SocialButtonsLayout.Top => V1alpha1BrandingThemeSocialButtonsLayout.Top, - SocialButtonsLayout.Bottom => V1alpha1BrandingThemeSocialButtonsLayout.Bottom, + BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Top => V1alpha1BrandingThemeSocialButtonsLayout.Top, + BrandingThemeWidgetSocialButtonsLayoutEnum.Values.Bottom => V1alpha1BrandingThemeSocialButtonsLayout.Bottom, _ => throw new InvalidOperationException() }; @@ -415,12 +354,12 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeLogoPosition? FromApi(LogoPosition source) => source switch + internal static V1alpha1BrandingThemeLogoPosition? FromApi(BrandingThemeWidgetLogoPositionEnum source) => source.Value switch { - LogoPosition.Center => V1alpha1BrandingThemeLogoPosition.Center, - LogoPosition.Left => V1alpha1BrandingThemeLogoPosition.Left, - LogoPosition.Right => V1alpha1BrandingThemeLogoPosition.Right, - LogoPosition.None => V1alpha1BrandingThemeLogoPosition.None, + BrandingThemeWidgetLogoPositionEnum.Values.Center => V1alpha1BrandingThemeLogoPosition.Center, + BrandingThemeWidgetLogoPositionEnum.Values.Left => V1alpha1BrandingThemeLogoPosition.Left, + BrandingThemeWidgetLogoPositionEnum.Values.Right => V1alpha1BrandingThemeLogoPosition.Right, + BrandingThemeWidgetLogoPositionEnum.Values.None => V1alpha1BrandingThemeLogoPosition.None, _ => throw new InvalidOperationException() }; @@ -430,11 +369,11 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeHeaderTextAlignment? FromApi(HeaderTextAlignment source) => source switch + internal static V1alpha1BrandingThemeHeaderTextAlignment? FromApi(BrandingThemeWidgetHeaderTextAlignmentEnum source) => source.Value switch { - HeaderTextAlignment.Center => V1alpha1BrandingThemeHeaderTextAlignment.Center, - HeaderTextAlignment.Left => V1alpha1BrandingThemeHeaderTextAlignment.Left, - HeaderTextAlignment.Right => V1alpha1BrandingThemeHeaderTextAlignment.Right, + BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Center => V1alpha1BrandingThemeHeaderTextAlignment.Center, + BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Left => V1alpha1BrandingThemeHeaderTextAlignment.Left, + BrandingThemeWidgetHeaderTextAlignmentEnum.Values.Right => V1alpha1BrandingThemeHeaderTextAlignment.Right, _ => throw new InvalidOperationException() }; @@ -443,7 +382,7 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemePageBackground FromApi(BrandingThemePageBackground source) => new() + internal static V1alpha1BrandingThemePageBackground? FromApi(BrandingThemePageBackground? source) => source is null ? null : new() { BackgroundColor = source.BackgroundColor, BackgroundImageUrl = source.BackgroundImageUrl, @@ -456,11 +395,11 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemePageLayout? FromApi(PageLayout source) => source switch + internal static V1alpha1BrandingThemePageLayout? FromApi(BrandingThemePageBackgroundPageLayoutEnum source) => source.Value switch { - PageLayout.Center => V1alpha1BrandingThemePageLayout.Center, - PageLayout.Left => V1alpha1BrandingThemePageLayout.Left, - PageLayout.Right => V1alpha1BrandingThemePageLayout.Right, + BrandingThemePageBackgroundPageLayoutEnum.Values.Center => V1alpha1BrandingThemePageLayout.Center, + BrandingThemePageBackgroundPageLayoutEnum.Values.Left => V1alpha1BrandingThemePageLayout.Left, + BrandingThemePageBackgroundPageLayoutEnum.Values.Right => V1alpha1BrandingThemePageLayout.Right, _ => throw new InvalidOperationException(), }; @@ -469,7 +408,7 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeFonts FromApi(BrandingThemeFonts source) => new() + internal static V1alpha1BrandingThemeFonts? FromApi(BrandingThemeFonts? source) => source is null ? null : new() { BodyText = FromApi(source.BodyText), ButtonsText = FromApi(source.ButtonsText), @@ -477,7 +416,7 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra InputLabels = FromApi(source.InputLabels), Links = FromApi(source.Links), LinksStyle = FromApi(source.LinksStyle), - ReferenceTextSize = source.ReferenceTextSize, + ReferenceTextSize = (float)source.ReferenceTextSize, Subtitle = FromApi(source.Subtitle), Title = FromApi(source.Title) }; @@ -487,10 +426,10 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeFont FromApi(Title source) => new() + internal static V1alpha1BrandingThemeFont? FromApi(BrandingThemeFontTitle? source) => source is null ? null : new() { Bold = source.Bold, - Size = source.Size + Size = (float)source.Size }; /// @@ -498,10 +437,10 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeFont FromApi(Links source) => new() + internal static V1alpha1BrandingThemeFont? FromApi(BrandingThemeFontLinks? source) => source is null ? null : new() { Bold = source.Bold, - Size = source.Size + Size = (float)source.Size }; /// @@ -509,10 +448,10 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeFont FromApi(Subtitle source) => new() + internal static V1alpha1BrandingThemeFont? FromApi(BrandingThemeFontSubtitle? source) => source is null ? null : new() { Bold = source.Bold, - Size = source.Size + Size = (float)source.Size }; /// @@ -521,10 +460,10 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeLinksStyle? FromApi(LinksStyle source) => source switch + internal static V1alpha1BrandingThemeLinksStyle? FromApi(BrandingThemeFontLinksStyleEnum source) => source.Value switch { - LinksStyle.Normal => V1alpha1BrandingThemeLinksStyle.Normal, - LinksStyle.Underlined => V1alpha1BrandingThemeLinksStyle.Underlined, + BrandingThemeFontLinksStyleEnum.Values.Normal => V1alpha1BrandingThemeLinksStyle.Normal, + BrandingThemeFontLinksStyleEnum.Values.Underlined => V1alpha1BrandingThemeLinksStyle.Underlined, _ => throw new InvalidOperationException() }; @@ -533,10 +472,10 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeFont FromApi(InputLabels source) => new() + internal static V1alpha1BrandingThemeFont? FromApi(BrandingThemeFontInputLabels? source) => source is null ? null : new() { Bold = source.Bold, - Size = source.Size + Size = (float)source.Size }; /// @@ -544,10 +483,10 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeFont FromApi(ButtonsText source) => new() + internal static V1alpha1BrandingThemeFont? FromApi(BrandingThemeFontButtonsText? source) => source is null ? null : new() { Bold = source.Bold, - Size = source.Size + Size = (float)source.Size }; /// @@ -555,10 +494,10 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeFont FromApi(BodyText source) => new() + internal static V1alpha1BrandingThemeFont? FromApi(BrandingThemeFontBodyText? source) => source is null ? null : new() { Bold = source.Bold, - Size = source.Size + Size = (float)source.Size }; /// @@ -566,12 +505,12 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeColors FromApi(BrandingThemeColors source) => new() + internal static V1alpha1BrandingThemeColors? FromApi(BrandingThemeColors? source) => source is null ? null : new() { BaseFocusColor = source.BaseFocusColor, BaseHoverColor = source.BaseHoverColor, BodyText = source.BodyText, - CaptchaWidgetTheme = FromApi(source.CaptchaWidgetTheme), + CaptchaWidgetTheme = source.CaptchaWidgetTheme is { } cwt ? FromApi(cwt) : null, Error = source.Error, Header = source.Header, Icons = source.Icons, @@ -595,11 +534,11 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeCaptchaWidgetTheme? FromApi(CaptchaWidgetTheme source) => source switch + internal static V1alpha1BrandingThemeCaptchaWidgetTheme? FromApi(BrandingThemeColorsCaptchaWidgetThemeEnum source) => source.Value switch { - CaptchaWidgetTheme.Light => V1alpha1BrandingThemeCaptchaWidgetTheme.Light, - CaptchaWidgetTheme.Dark => V1alpha1BrandingThemeCaptchaWidgetTheme.Dark, - CaptchaWidgetTheme.Auto => V1alpha1BrandingThemeCaptchaWidgetTheme.Auto, + BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Light => V1alpha1BrandingThemeCaptchaWidgetTheme.Light, + BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Dark => V1alpha1BrandingThemeCaptchaWidgetTheme.Dark, + BrandingThemeColorsCaptchaWidgetThemeEnum.Values.Auto => V1alpha1BrandingThemeCaptchaWidgetTheme.Auto, _ => throw new InvalidOperationException() }; @@ -608,15 +547,15 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// /// - internal static V1alpha1BrandingThemeBorders? FromApi(BrandingThemeBorder source) => new() + internal static V1alpha1BrandingThemeBorders? FromApi(BrandingThemeBorders? source) => source is null ? null : new() { - ButtonBorderRadius = source.ButtonBorderRadius, - ButtonBorderWeight = source.ButtonBorderWeight, - InputBorderRadius = source.InputBorderRadius, - InputBorderWeight = source.InputBorderWeight, + ButtonBorderRadius = (float)source.ButtonBorderRadius, + ButtonBorderWeight = (float)source.ButtonBorderWeight, + InputBorderRadius = (float)source.InputBorderRadius, + InputBorderWeight = (float)source.InputBorderWeight, ShowWidgetShadow = source.ShowWidgetShadow, - WidgetBorderWeight = source.WidgetBorderWeight, - WidgetCornerRadius = source.WidgetCornerRadius, + WidgetBorderWeight = (float)source.WidgetBorderWeight, + WidgetCornerRadius = (float)source.WidgetCornerRadius, ButtonsStyle = FromApi(source.ButtonsStyle), InputsStyle = FromApi(source.InputsStyle), }; @@ -624,14 +563,28 @@ internal static void ApplyToApi(V1alpha1BrandingThemePageBackground? source, Bra /// /// Transforms the specified source from the API type. /// - /// + /// + /// + /// + internal static V1alpha1BrandingThemeButtonsStyle FromApi(BrandingThemeBordersButtonsStyleEnum source) => source.Value switch + { + BrandingThemeBordersButtonsStyleEnum.Values.Pill => V1alpha1BrandingThemeButtonsStyle.Pill, + BrandingThemeBordersButtonsStyleEnum.Values.Rounded => V1alpha1BrandingThemeButtonsStyle.Rounded, + BrandingThemeBordersButtonsStyleEnum.Values.Sharp => V1alpha1BrandingThemeButtonsStyle.Sharp, + _ => throw new NotImplementedException(), + }; + + /// + /// Transforms the specified source from the API type. + /// + /// /// /// - internal static V1alpha1BrandingThemeButtonsStyle FromApi(ButtonsStyle inputsStyle) => inputsStyle switch + internal static V1alpha1BrandingThemeButtonsStyle FromApi(BrandingThemeBordersInputsStyleEnum source) => source.Value switch { - ButtonsStyle.Pill => V1alpha1BrandingThemeButtonsStyle.Pill, - ButtonsStyle.Rounded => V1alpha1BrandingThemeButtonsStyle.Rounded, - ButtonsStyle.Sharp => V1alpha1BrandingThemeButtonsStyle.Sharp, + BrandingThemeBordersInputsStyleEnum.Values.Pill => V1alpha1BrandingThemeButtonsStyle.Pill, + BrandingThemeBordersInputsStyleEnum.Values.Rounded => V1alpha1BrandingThemeButtonsStyle.Rounded, + BrandingThemeBordersInputsStyleEnum.Values.Sharp => V1alpha1BrandingThemeButtonsStyle.Sharp, _ => throw new NotImplementedException(), }; @@ -656,7 +609,7 @@ public V1alpha1BrandingThemeController(IKubernetesClient kube, IMemoryCache cach { try { - return FromApi(await api.Branding.GetBrandingThemeAsync(id, cancellationToken: cancellationToken)); + return FromApi(await api.Branding.Themes.GetAsync(id, cancellationToken: cancellationToken)); } catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) { @@ -673,7 +626,7 @@ public V1alpha1BrandingThemeController(IKubernetesClient kube, IMemoryCache cach { try { - var theme = await api.Branding.GetBrandingThemeAsync(id, cancellationToken); + var theme = await api.Branding.Themes.GetAsync(id, cancellationToken: cancellationToken); Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} found existing theme: {DisplayName}", EntityTypeName, entity.Namespace(), entity.Name(), theme.DisplayName); return theme.ThemeId; } @@ -703,10 +656,7 @@ protected override async Task Create(IManagementApiClient api, V1alpha1B { Logger.LogInformation("{EntityTypeName} creating theme in Auth0 with name: {ThemeName}", EntityTypeName, conf.DisplayName); - var req = new BrandingThemeCreateRequest(); - ApplyToApi(conf, req); - - var self = await api.Branding.CreateBrandingThemeAsync(req, cancellationToken); + var self = await api.Branding.Themes.CreateAsync(ToCreateRequest(conf), cancellationToken: cancellationToken); Logger.LogInformation("{EntityTypeName} successfully created theme in Auth0 with ID: {ThemeId} and name: {ThemeName}", EntityTypeName, self.ThemeId, conf.DisplayName); return self.ThemeId; } @@ -716,12 +666,9 @@ protected override async Task Update(IManagementApiClient api, string id, V1alph { Logger.LogInformation("{EntityTypeName} updating theme in Auth0 with id: {ThemeId} and name: {ThemeName}", EntityTypeName, id, conf.DisplayName); - // apply last conf to request to ensure we don't overwrite any properties not managed by us - var req = new BrandingThemeUpdateRequest(); - ApplyToApi(last, req); - ApplyToApi(conf, req); - - await api.Branding.UpdateBrandingThemeAsync(id, req, cancellationToken); + // fetch the current state so unmanaged fields are preserved + var self = await api.Branding.Themes.GetAsync(id, cancellationToken: cancellationToken); + await api.Branding.Themes.UpdateAsync(id, ToUpdateRequest(conf, self), cancellationToken: cancellationToken); Logger.LogInformation("{EntityTypeName} successfully updated theme in Auth0 with id: {ThemeId} and name: {ThemeName}", EntityTypeName, id, conf.DisplayName); } @@ -735,7 +682,7 @@ protected override async Task ApplyStatus(IManagementApiClient api, V1alpha1Bran protected override async Task DeletedAsync(IManagementApiClient api, string id, CancellationToken cancellationToken) { Logger.LogInformation("{EntityTypeName} deleting theme from Auth0 with ID: {ThemeId} (reason: Kubernetes entity deleted)", EntityTypeName, id); - await api.Branding.DeleteBrandingThemeAsync(id, cancellationToken); + await api.Branding.Themes.DeleteAsync(id, cancellationToken: cancellationToken); Logger.LogInformation("{EntityTypeName} successfully deleted theme from Auth0 with ID: {ThemeId}", EntityTypeName, id); } diff --git a/src/Alethic.Auth0.Operator/Controllers/V1alpha1CustomDomainController.cs b/src/Alethic.Auth0.Operator/Controllers/V1alpha1CustomDomainController.cs index 6bacdc0..8b2cf2f 100644 --- a/src/Alethic.Auth0.Operator/Controllers/V1alpha1CustomDomainController.cs +++ b/src/Alethic.Auth0.Operator/Controllers/V1alpha1CustomDomainController.cs @@ -10,7 +10,7 @@ using Auth0.Core.Exceptions; using Auth0.ManagementApi; -using Auth0.ManagementApi.Models; +using Auth0.ManagementApi.Core; using k8s.Models; @@ -40,10 +40,10 @@ public class V1alpha1CustomDomainController : /// /// /// - static CustomDomainCertificateProvisioning ToApi(V1alpha1CustomDomainCertificateProvisioning value) => value switch + static CustomDomainProvisioningTypeEnum ToApi(V1alpha1CustomDomainCertificateProvisioning value) => value switch { - V1alpha1CustomDomainCertificateProvisioning.Auth0ManagedCertificate => CustomDomainCertificateProvisioning.Auth0ManagedCertificate, - V1alpha1CustomDomainCertificateProvisioning.SelfManagedCertificate => CustomDomainCertificateProvisioning.SelfManagedCertificate, + V1alpha1CustomDomainCertificateProvisioning.Auth0ManagedCertificate => CustomDomainProvisioningTypeEnum.Auth0ManagedCerts, + V1alpha1CustomDomainCertificateProvisioning.SelfManagedCertificate => CustomDomainProvisioningTypeEnum.SelfManagedCerts, _ => throw new InvalidOperationException() }; @@ -61,46 +61,34 @@ public class V1alpha1CustomDomainController : }; /// - /// Applies the specified configuration to the target. + /// Builds a from the specified configuration. /// /// - /// - static void ApplyToApi(V1alpha1CustomDomainConf? source, CustomDomainCreateRequest target) + /// + static CreateCustomDomainRequestContent ToCreateRequest(V1alpha1CustomDomainConf source) => new() { - if (source is null) - return; - - if (source.Domain is not null) - target.Domain = source.Domain; - - if (source.Type is not null) - target.Type = ToApi(source.Type.Value); - - if (source.VerificationMethod is not null) - target.VerificationMethod = ToApi(source.VerificationMethod.Value); - - if (source.TlsPolicy is not null) - target.TlsPolicy = source.TlsPolicy; - - if (source.CustomClientIpHeader is not null) - target.CustomClientIpHeader = source.CustomClientIpHeader; - } + Domain = source.Domain ?? throw new InvalidOperationException("Domain is required."), + Type = source.Type is not null ? ToApi(source.Type.Value) : throw new InvalidOperationException("Type is required."), + VerificationMethod = source.VerificationMethod is not null ? new CustomDomainVerificationMethodEnum(ToApi(source.VerificationMethod.Value)) : null, + TlsPolicy = source.TlsPolicy is not null ? new CustomDomainTlsPolicyEnum(source.TlsPolicy) : null, + CustomClientIpHeader = source.CustomClientIpHeader is not null ? Optional.Of(new CustomDomainCustomClientIpHeaderEnum(source.CustomClientIpHeader)) : default, + }; /// /// Applies the specified configuration to the target. /// /// /// - static void ApplyToApi(V1alpha1CustomDomainConf? source, CustomDomainUpdateRequest target) + static void ApplyToApi(V1alpha1CustomDomainConf? source, UpdateCustomDomainRequestContent target) { if (source is null) return; if (source.TlsPolicy is not null) - target.TlsPolicy = source.TlsPolicy; + target.TlsPolicy = new CustomDomainTlsPolicyEnum(source.TlsPolicy); if (source.CustomClientIpHeader is not null) - target.CustomClientIpHeader = source.CustomClientIpHeader; + target.CustomClientIpHeader = Optional.Of(new CustomDomainCustomClientIpHeaderEnum(source.CustomClientIpHeader)); } /// @@ -109,10 +97,10 @@ static void ApplyToApi(V1alpha1CustomDomainConf? source, CustomDomainUpdateReque /// /// /// - static V1alpha1CustomDomainCertificateProvisioning? FromApi(CustomDomainCertificateProvisioning? value) => value switch + static V1alpha1CustomDomainCertificateProvisioning? FromApi(CustomDomainTypeEnum? value) => value?.Value switch { - CustomDomainCertificateProvisioning.Auth0ManagedCertificate => V1alpha1CustomDomainCertificateProvisioning.Auth0ManagedCertificate, - CustomDomainCertificateProvisioning.SelfManagedCertificate => V1alpha1CustomDomainCertificateProvisioning.SelfManagedCertificate, + CustomDomainTypeEnum.Values.Auth0ManagedCerts => V1alpha1CustomDomainCertificateProvisioning.Auth0ManagedCertificate, + CustomDomainTypeEnum.Values.SelfManagedCerts => V1alpha1CustomDomainCertificateProvisioning.SelfManagedCertificate, null => null, _ => throw new InvalidOperationException() }; @@ -137,13 +125,13 @@ static void ApplyToApi(V1alpha1CustomDomainConf? source, CustomDomainUpdateReque /// /// /// - static V1alpha1CustomDomainConf FromApi(CustomDomain source) => new() + static V1alpha1CustomDomainConf FromApi(GetCustomDomainResponseContent source) => new() { Domain = source.Domain, Type = FromApi(source.Type), - VerificationMethod = source.Verification.Methods.Length > 0 ? FromApi(source.Verification.Methods[0].Name) : null, + VerificationMethod = source.Verification?.Methods?.FirstOrDefault() is { } m ? FromApi(m.Name.Value) : null, TlsPolicy = source.TlsPolicy, - CustomClientIpHeader = source.CustomClientIpHeader, + CustomClientIpHeader = source.CustomClientIpHeader.Value, // Optional → string? Primary = source.Primary }; @@ -168,7 +156,7 @@ public V1alpha1CustomDomainController(IKubernetesClient kube, IMemoryCache cache { try { - return FromApi(await api.CustomDomains.GetAsync(id, cancellationToken)); + return FromApi(await api.CustomDomains.GetAsync(id, cancellationToken: cancellationToken)); } catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) { @@ -183,7 +171,7 @@ public V1alpha1CustomDomainController(IKubernetesClient kube, IMemoryCache cache if (conf is null) return null; - var list = await api.CustomDomains.GetAllAsync(cancellationToken); + var list = await api.CustomDomains.ListAsync(new ListCustomDomainsRequestParameters(), cancellationToken: cancellationToken); var self = list.FirstOrDefault(i => i.Domain == conf.Domain); return self?.CustomDomainId; } @@ -199,10 +187,9 @@ protected override async Task Create(IManagementApiClient api, V1alpha1C { Logger.LogInformation("{EntityTypeName} creating custom domain in Auth0 with name: {Domain}", EntityTypeName, conf.Domain); - var req = new CustomDomainCreateRequest(); - ApplyToApi(conf, req); + var req = ToCreateRequest(conf); - var self = await api.CustomDomains.CreateAsync(req, cancellationToken); + var self = await api.CustomDomains.CreateAsync(req, cancellationToken: cancellationToken); Logger.LogInformation("{EntityTypeName} successfully created custom domain in Auth0 with ID: {CustomDomainId} and name: {Domain}", EntityTypeName, self.CustomDomainId, conf.Domain); return self.CustomDomainId; } @@ -212,12 +199,11 @@ protected override async Task Update(IManagementApiClient api, string id, V1alph { Logger.LogInformation("{EntityTypeName} updating custom domain in Auth0 with id: {CustomDomainId} and name: {Domain}", EntityTypeName, id, conf.Domain); - // apply last conf to request to ensure we don't overwrite any properties not managed by us - var req = new CustomDomainUpdateRequest(); + var req = new UpdateCustomDomainRequestContent(); ApplyToApi(last, req); ApplyToApi(conf, req); - await api.CustomDomains.UpdateAsync(id, req, cancellationToken); + await api.CustomDomains.UpdateAsync(id, req, cancellationToken: cancellationToken); Logger.LogInformation("{EntityTypeName} successfully updated custom domain in Auth0 with id: {CustomDomainId} and name: {Domain}", EntityTypeName, id, conf.Domain); } @@ -231,7 +217,7 @@ protected override async Task ApplyStatus(IManagementApiClient api, V1alpha1Cust protected override async Task DeletedAsync(IManagementApiClient api, string id, CancellationToken cancellationToken) { Logger.LogInformation("{EntityTypeName} deleting custom domain from Auth0 with ID: {Domain} (reason: Kubernetes entity deleted)", EntityTypeName, id); - await api.CustomDomains.DeleteAsync(id, cancellationToken); + await api.CustomDomains.DeleteAsync(id, cancellationToken: cancellationToken); Logger.LogInformation("{EntityTypeName} successfully deleted custom domain from Auth0 with ID: {Domain}", EntityTypeName, id); } diff --git a/src/Alethic.Auth0.Operator/Controllers/V1alpha1CustomTextController.cs b/src/Alethic.Auth0.Operator/Controllers/V1alpha1CustomTextController.cs index 28a12ae..496b6c0 100644 --- a/src/Alethic.Auth0.Operator/Controllers/V1alpha1CustomTextController.cs +++ b/src/Alethic.Auth0.Operator/Controllers/V1alpha1CustomTextController.cs @@ -19,8 +19,6 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using Newtonsoft.Json.Linq; - namespace Alethic.Auth0.Operator.Controllers { @@ -33,26 +31,42 @@ public class V1alpha1CustomTextController : IEntityController { - static V1alpha1CustomTextScreen FromApiScreen(JObject source) + static V1alpha1CustomTextScreen FromApiScreen(Dictionary source) { var screen = new V1alpha1CustomTextScreen(); - foreach (var prop in source.Properties()) - screen[prop.Name] = prop.Value.Value() ?? string.Empty; + foreach (var kvp in source) + screen[kvp.Key] = kvp.Value?.ToString() ?? string.Empty; return screen; } - static Dictionary? FromApiScreens(object? source) + static Dictionary? FromApiScreens(Dictionary? source) { - if (source is not JObject root) + if (source is null) return null; var result = new Dictionary(); - foreach (var prop in root.Properties()) - if (prop.Value is JObject screenObj) - result[prop.Name] = FromApiScreen(screenObj); + foreach (var kvp in source) + if (kvp.Value is Dictionary screenDict) + result[kvp.Key] = FromApiScreen(screenDict); + + return result; + } + + static Dictionary ToApiScreens(Dictionary source) + { + var result = new Dictionary(); + + foreach (var kvp in source) + { + var screen = new Dictionary(); + foreach (var entry in kvp.Value) + screen[entry.Key] = entry.Value; + + result[kvp.Key] = screen; + } return result; } @@ -82,7 +96,10 @@ protected override async Task ReconcileAsync(IManagementApiC if (entity.Spec.Language is null) throw new InvalidOperationException($"{EntityTypeName} {entity.Namespace()}/{entity.Name()} missing language."); - var screens = await api.Prompts.GetCustomTextForPromptAsync(entity.Spec.Prompt, entity.Spec.Language, cancellationToken: cancellationToken); + var prompt = new PromptGroupNameEnum(entity.Spec.Prompt); + var language = new PromptLanguageEnum(entity.Spec.Language); + + var screens = await api.Prompts.CustomText.GetAsync(prompt, language, cancellationToken: cancellationToken); if (screens is null) throw new RetryException($"{EntityTypeName} {entity.Namespace()}/{entity.Name()} custom text cannot be loaded from API."); @@ -93,8 +110,8 @@ protected override async Task ReconcileAsync(IManagementApiC if (conf.Screens is { } newScreens) { // push changes to Auth0 and reload resulting configuration - await api.Prompts.SetCustomTextForPromptAsync(entity.Spec.Prompt, entity.Spec.Language, newScreens, cancellationToken); - screens = await api.Prompts.GetCustomTextForPromptAsync(entity.Spec.Prompt, entity.Spec.Language, cancellationToken: cancellationToken); + await api.Prompts.CustomText.SetAsync(prompt, language, ToApiScreens(newScreens), cancellationToken: cancellationToken); + screens = await api.Prompts.CustomText.GetAsync(prompt, language, cancellationToken: cancellationToken); } } diff --git a/src/Alethic.Auth0.Operator/Controllers/V2alpha1ClientController.cs b/src/Alethic.Auth0.Operator/Controllers/V2alpha1ClientController.cs new file mode 100644 index 0000000..0f6d250 --- /dev/null +++ b/src/Alethic.Auth0.Operator/Controllers/V2alpha1ClientController.cs @@ -0,0 +1,1433 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; + +using Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; +using Alethic.Auth0.Operator.Models; +using Alethic.Auth0.Operator.Options; + +using Auth0.Core.Exceptions; +using Auth0.ManagementApi; + +using k8s.Models; + +using KubeOps.Abstractions.Entities; +using KubeOps.Abstractions.Rbac; +using KubeOps.Abstractions.Reconciliation.Controller; +using KubeOps.KubernetesClient; + +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Alethic.Auth0.Operator.Controllers +{ + + [EntityRbac(typeof(V2alpha1Client), Verbs = RbacVerb.All)] + [EntityRbac(typeof(V1Secret), Verbs = RbacVerb.All)] + [EntityRbac(typeof(V2alpha1Tenant), Verbs = RbacVerb.List | RbacVerb.Get)] + [EntityRbac(typeof(V1Secret), Verbs = RbacVerb.List | RbacVerb.Get)] + [EntityRbac(typeof(Eventsv1Event), Verbs = RbacVerb.All)] + public class V2alpha1ClientController : + V1TenantEntityInstanceController, + IEntityController + { + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientConf? FromApi(GetClientResponseContent? source) => source is null ? null : new() + { + AllowedClients = source.AllowedClients?.ToArray(), + AllowedLogoutUrls = source.AllowedLogoutUrls?.ToArray(), + AllowedOrigins = source.AllowedOrigins?.ToArray(), + WebOrigins = source.WebOrigins?.ToArray(), + InitiateLoginUri = source.InitiateLoginUri, + Callbacks = source.Callbacks?.ToArray(), + ClientAliases = source.ClientAliases?.ToArray(), + ClientMetaData = source.ClientMetadata, + IsCustomLoginPageOn = source.CustomLoginPageOn, + IsFirstParty = source.IsFirstParty, + CustomLoginPage = source.CustomLoginPage, + CustomLoginPagePreview = source.CustomLoginPagePreview, + FormTemplate = source.FormTemplate, + GrantTypes = source.GrantTypes?.ToArray(), + Name = source.Name, + Description = source.Description, + LogoUri = source.LogoUri, + OidcConformant = source.OidcConformant, + Sso = source.Sso, + CrossOriginAuthentication = source.CrossOriginAuthentication, + RequirePushedAuthorizationRequests = source.RequirePushedAuthorizationRequests, + RequireProofOfPossession = source.RequireProofOfPossession, + AddOns = source.Addons is { } addons ? FromApi(addons) : null, + ApplicationType = FromApi(source.AppType), + ComplianceLevel = source.ComplianceLevel.IsDefined && source.ComplianceLevel.Value is { } complianceLevel ? FromApi(complianceLevel) : null, + DefaultOrganization = source.DefaultOrganization.IsDefined && source.DefaultOrganization.Value is { } defaultOrganization ? FromApi(defaultOrganization) : null, + EncryptionKey = source.EncryptionKey.IsDefined && source.EncryptionKey.Value is { } encryptionKey ? FromApi(encryptionKey) : null, + JwtConfiguration = source.JwtConfiguration is { } jwtConfiguration ? FromApi(jwtConfiguration) : null, + Mobile = source.Mobile is { } mobile ? FromApi(mobile) : null, + OidcLogout = source.OidcLogout is { } oidcLogout ? FromApi(oidcLogout) : null, + OrganizationRequireBehavior = FromApi(source.OrganizationRequireBehavior), + OrganizationUsage = FromApi(source.OrganizationUsage), + RefreshToken = source.RefreshToken.IsDefined && source.RefreshToken.Value is { } refreshToken ? FromApi(refreshToken) : null, + SigningKeys = source.SigningKeys.IsDefined ? source.SigningKeys.Value?.Select(FromApi).ToArray() : null, + TokenEndpointAuthMethod = FromApi(source.TokenEndpointAuthMethod), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientTokenEndpointAuthMethodEnum? FromApi(ClientTokenEndpointAuthMethodEnum? source) => source?.Value switch + { + ClientTokenEndpointAuthMethodEnum.Values.None => V2alpha1ClientTokenEndpointAuthMethodEnum.None, + ClientTokenEndpointAuthMethodEnum.Values.ClientSecretPost => V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretPost, + ClientTokenEndpointAuthMethodEnum.Values.ClientSecretBasic => V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretBasic, + null => null, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientSigningKey? FromApi(ClientSigningKey? source) => source is null ? null : new() + { + Cert = source.Cert, + Pkcs7 = source.Pkcs7, + Subject = source.Subject, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientRefreshTokenConfiguration? FromApi(ClientRefreshTokenConfiguration? source) => source is null ? null : new() + { + ExpirationType = FromApi(source.ExpirationType), + InfiniteIdleTokenLifetime = source.InfiniteIdleTokenLifetime, + InfiniteTokenLifetime = source.InfiniteTokenLifetime, + Leeway = source.Leeway, + RotationType = FromApi(source.RotationType), + TokenLifetime = source.TokenLifetime, + IdleTokenLifetime = source.IdleTokenLifetime, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientRefreshTokenRotationTypeEnum? FromApi(RefreshTokenRotationTypeEnum? source) => source?.Value switch + { + RefreshTokenRotationTypeEnum.Values.Rotating => V2alpha1ClientRefreshTokenRotationTypeEnum.Rotating, + RefreshTokenRotationTypeEnum.Values.NonRotating => V2alpha1ClientRefreshTokenRotationTypeEnum.NonRotating, + null => null, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientRefreshTokenExpirationTypeEnum? FromApi(RefreshTokenExpirationTypeEnum? source) => source?.Value switch + { + RefreshTokenExpirationTypeEnum.Values.Expiring => V2alpha1ClientRefreshTokenExpirationTypeEnum.Expiring, + RefreshTokenExpirationTypeEnum.Values.NonExpiring => V2alpha1ClientRefreshTokenExpirationTypeEnum.NonExpiring, + null => null, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientOrganizationUsageEnum? FromApi(ClientOrganizationUsageEnum? source) => source?.Value switch + { + ClientOrganizationUsageEnum.Values.Deny => V2alpha1ClientOrganizationUsageEnum.Deny, + ClientOrganizationUsageEnum.Values.Allow => V2alpha1ClientOrganizationUsageEnum.Allow, + ClientOrganizationUsageEnum.Values.Require => V2alpha1ClientOrganizationUsageEnum.Require, + null => null, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientOrganizationRequireBehaviorEnum? FromApi(ClientOrganizationRequireBehaviorEnum? source) => source?.Value switch + { + ClientOrganizationRequireBehaviorEnum.Values.NoPrompt => V2alpha1ClientOrganizationRequireBehaviorEnum.NoPrompt, + ClientOrganizationRequireBehaviorEnum.Values.PreLoginPrompt => V2alpha1ClientOrganizationRequireBehaviorEnum.PreLoginPrompt, + ClientOrganizationRequireBehaviorEnum.Values.PostLoginPrompt => V2alpha1ClientOrganizationRequireBehaviorEnum.PostLoginPrompt, + null => null, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientOidcBackchannelLogoutSettings? FromApi(ClientOidcBackchannelLogoutSettings? source) => source is null ? null : new() + { + BackchannelLogoutUrls = source.BackchannelLogoutUrls?.ToArray(), + BackchannelLogoutInitiators = source.BackchannelLogoutInitiators is { } initiators ? FromApi(initiators) : null, + BackchannelLogoutSessionMetadata = source.BackchannelLogoutSessionMetadata.IsDefined && source.BackchannelLogoutSessionMetadata.Value is { } sessionMetadata + ? FromApi(sessionMetadata) + : null, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientOidcBackchannelLogoutSessionMetadata? FromApi(ClientOidcBackchannelLogoutSessionMetadata? source) => source is null ? null : new() + { + Include = source.Include, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientOidcBackchannelLogoutInitiators? FromApi(ClientOidcBackchannelLogoutInitiators? source) => source is null ? null : new() + { + Mode = FromApi(source.Mode), + SelectedInitiators = source.SelectedInitiators?.Select(FromApi).ToArray(), + }; + + internal static V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum FromApi(ClientOidcBackchannelLogoutInitiatorsEnum source) => source.Value switch + { + ClientOidcBackchannelLogoutInitiatorsEnum.Values.RpLogout => V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.RpLogout, + ClientOidcBackchannelLogoutInitiatorsEnum.Values.IdpLogout => V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.IdpLogout, + ClientOidcBackchannelLogoutInitiatorsEnum.Values.PasswordChanged => V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.PasswordChanged, + ClientOidcBackchannelLogoutInitiatorsEnum.Values.SessionExpired => V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.SessionExpired, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum? FromApi(ClientOidcBackchannelLogoutInitiatorsModeEnum? source) => source?.Value switch + { + ClientOidcBackchannelLogoutInitiatorsModeEnum.Values.All => V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.All, + ClientOidcBackchannelLogoutInitiatorsModeEnum.Values.Custom => V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.Custom, + null => null, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientMobile? FromApi(ClientMobile? source) => source is null ? null : new() + { + Android = source.Android is { } android ? FromApi(android) : null, + Ios = source.Ios is { } ios ? FromApi(ios) : null, + }; + + internal static V2alpha1ClientMobileiOs? FromApi(ClientMobileiOs? source) + { + if (source is null) + return null; + if (source.AppBundleIdentifier is null && source.TeamId is null) + return null; + + return new() + { + AppBundleIdentifier = source.AppBundleIdentifier, + TeamId = source.TeamId, + }; + } + + internal static V2alpha1ClientMobileAndroid? FromApi(ClientMobileAndroid? source) + { + if (source is null) + return null; + if (source.AppPackageName is null) + return null; + + return new() + { + AppPackageName = source.AppPackageName, + }; + } + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientJwtConfiguration? FromApi(ClientJwtConfiguration? source) => source is null ? null : new() + { + SecretEncoded = source.SecretEncoded, + LifetimeInSeconds = source.LifetimeInSeconds, + Alg = FromApi(source.Alg), + Scopes = source.Scopes, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientSigningAlgorithmEnum? FromApi(SigningAlgorithmEnum? source) => source?.Value switch + { + SigningAlgorithmEnum.Values.Hs256 => V2alpha1ClientSigningAlgorithmEnum.Hs256, + SigningAlgorithmEnum.Values.Rs256 => V2alpha1ClientSigningAlgorithmEnum.Rs256, + SigningAlgorithmEnum.Values.Rs512 => V2alpha1ClientSigningAlgorithmEnum.Rs512, + SigningAlgorithmEnum.Values.Ps256 => V2alpha1ClientSigningAlgorithmEnum.Ps256, + null => null, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientEncryptionKey? FromApi(ClientEncryptionKey? source) => source is null ? null : new() + { + Cert = source.Cert, + Pub = source.Pub, + Subject = source.Subject, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientDefaultOrganization? FromApi(ClientDefaultOrganization? source) => source is null ? null : new() + { + OrganizationId = source.OrganizationId, + Flows = source.Flows?.Select(FromApi).ToArray(), + }; + + internal static V2alpha1ClientDefaultOrganizationFlowsEnum FromApi(ClientDefaultOrganizationFlowsEnum source) => source.Value switch + { + ClientDefaultOrganizationFlowsEnum.Values.ClientCredentials => V2alpha1ClientDefaultOrganizationFlowsEnum.ClientCredentials, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientComplianceLevelEnum? FromApi(ClientComplianceLevelEnum? source) => source?.Value switch + { + ClientComplianceLevelEnum.Values.None => V2alpha1ClientComplianceLevelEnum.None, + ClientComplianceLevelEnum.Values.Fapi1AdvPkjPar => V2alpha1ClientComplianceLevelEnum.Fapi1AdvPkjPar, + ClientComplianceLevelEnum.Values.Fapi1AdvMtlsPar => V2alpha1ClientComplianceLevelEnum.Fapi1AdvMtlsPar, + ClientComplianceLevelEnum.Values.Fapi2SpPkjMtls => V2alpha1ClientComplianceLevelEnum.Fapi2SpPkjMtls, + ClientComplianceLevelEnum.Values.Fapi2SpMtlsMtls => V2alpha1ClientComplianceLevelEnum.Fapi2SpMtlsMtls, + null => null, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAppTypeEnum? FromApi(ClientAppTypeEnum? source) => source?.Value switch + { + ClientAppTypeEnum.Values.Box => V2alpha1ClientAppTypeEnum.Box, + ClientAppTypeEnum.Values.Cloudbees => V2alpha1ClientAppTypeEnum.Cloudbees, + ClientAppTypeEnum.Values.Concur => V2alpha1ClientAppTypeEnum.Concur, + ClientAppTypeEnum.Values.Dropbox => V2alpha1ClientAppTypeEnum.Dropbox, + ClientAppTypeEnum.Values.Echosign => V2alpha1ClientAppTypeEnum.Echosign, + ClientAppTypeEnum.Values.Egnyte => V2alpha1ClientAppTypeEnum.Egnyte, + ClientAppTypeEnum.Values.Mscrm => V2alpha1ClientAppTypeEnum.Mscrm, + ClientAppTypeEnum.Values.Native => V2alpha1ClientAppTypeEnum.Native, + ClientAppTypeEnum.Values.Newrelic => V2alpha1ClientAppTypeEnum.Newrelic, + ClientAppTypeEnum.Values.NonInteractive => V2alpha1ClientAppTypeEnum.NonInteractive, + ClientAppTypeEnum.Values.Office365 => V2alpha1ClientAppTypeEnum.Office365, + ClientAppTypeEnum.Values.RegularWeb => V2alpha1ClientAppTypeEnum.RegularWeb, + ClientAppTypeEnum.Values.Rms => V2alpha1ClientAppTypeEnum.Rms, + ClientAppTypeEnum.Values.Salesforce => V2alpha1ClientAppTypeEnum.Salesforce, + ClientAppTypeEnum.Values.Sentry => V2alpha1ClientAppTypeEnum.Sentry, + ClientAppTypeEnum.Values.Sharepoint => V2alpha1ClientAppTypeEnum.Sharepoint, + ClientAppTypeEnum.Values.Slack => V2alpha1ClientAppTypeEnum.Slack, + ClientAppTypeEnum.Values.Springcm => V2alpha1ClientAppTypeEnum.Springcm, + ClientAppTypeEnum.Values.Spa => V2alpha1ClientAppTypeEnum.Spa, + ClientAppTypeEnum.Values.Zendesk => V2alpha1ClientAppTypeEnum.Zendesk, + ClientAppTypeEnum.Values.Zoom => V2alpha1ClientAppTypeEnum.Zoom, + ClientAppTypeEnum.Values.ResourceServer => V2alpha1ClientAppTypeEnum.ResourceServer, + ClientAppTypeEnum.Values.ExpressConfiguration => V2alpha1ClientAppTypeEnum.ExpressConfiguration, + ClientAppTypeEnum.Values.SsoIntegration => V2alpha1ClientAppTypeEnum.SsoIntegration, + ClientAppTypeEnum.Values.Oag => V2alpha1ClientAppTypeEnum.Oag, + null => null, + _ => throw new NotImplementedException(), + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddons? FromApi(ClientAddons? source) => source is null ? null : new() + { + Aws = source.Aws is { } aws ? FromApi(aws) : null, + AzureBlob = source.AzureBlob is { } azureBlob ? FromApi(azureBlob) : null, + AzureSb = source.AzureSb is { } azureSb ? FromApi(azureSb) : null, + Rms = source.Rms is { } rms ? FromApi(rms) : null, + Mscrm = source.Mscrm is { } mscrm ? FromApi(mscrm) : null, + Slack = source.Slack is { } slack ? FromApi(slack) : null, + Sentry = source.Sentry is { } sentry ? FromApi(sentry) : null, + Box = source.Box, + Cloudbees = source.Cloudbees, + Concur = source.Concur, + Dropbox = source.Dropbox, + Echosign = source.Echosign is { } echosign ? FromApi(echosign) : null, + Egnyte = source.Egnyte is { } egnyte ? FromApi(egnyte) : null, + Firebase = source.Firebase is { } firebase ? FromApi(firebase) : null, + Newrelic = source.Newrelic is { } newrelic ? FromApi(newrelic) : null, + Office365 = source.Office365 is { } office365 ? FromApi(office365) : null, + Salesforce = source.Salesforce is { } salesforce ? FromApi(salesforce) : null, + SalesforceApi = source.SalesforceApi is { } salesforceApi ? FromApi(salesforceApi) : null, + SalesforceSandboxApi = source.SalesforceSandboxApi is { } salesforceSandboxApi ? FromApi(salesforceSandboxApi) : null, + Samlp = source.Samlp is { } samlp ? FromApi(samlp) : null, + Layer = source.Layer is { } layer ? FromApi(layer) : null, + SapApi = source.SapApi is { } sapApi ? FromApi(sapApi) : null, + Sharepoint = source.Sharepoint is { } sharepoint ? FromApi(sharepoint) : null, + Springcm = source.Springcm is { } springcm ? FromApi(springcm) : null, + Wams = source.Wams is { } wams ? FromApi(wams) : null, + Wsfed = source.Wsfed, + Zendesk = source.Zendesk is { } zendesk ? FromApi(zendesk) : null, + Zoom = source.Zoom is { } zoom ? FromApi(zoom) : null, + SsoIntegration = source.SsoIntegration is { } ssoIntegration ? FromApi(ssoIntegration) : null, + Oag = source.Oag.IsDefined && source.Oag.Value is { } oag ? FromApi(oag) : null, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonAws? FromApi(ClientAddonAws? source) => source is null ? null : new() + { + Principal = source.Principal, + Role = source.Role, + LifetimeInSeconds = source.LifetimeInSeconds, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonAzureBlob? FromApi(ClientAddonAzureBlob? source) => source is null ? null : new() + { + AccountName = source.AccountName, + StorageAccessKey = source.StorageAccessKey, + ContainerName = source.ContainerName, + BlobName = source.BlobName, + Expiration = source.Expiration, + SignedIdentifier = source.SignedIdentifier, + BlobRead = source.BlobRead, + BlobWrite = source.BlobWrite, + BlobDelete = source.BlobDelete, + ContainerRead = source.ContainerRead, + ContainerWrite = source.ContainerWrite, + ContainerDelete = source.ContainerDelete, + ContainerList = source.ContainerList, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonAzureSb? FromApi(ClientAddonAzureSb? source) => source is null ? null : new() + { + Namespace = source.Namespace, + SasKeyName = source.SasKeyName, + SasKey = source.SasKey, + EntityPath = source.EntityPath, + Expiration = source.Expiration, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonRms? FromApi(ClientAddonRms? source) => source is null ? null : new() + { + Url = source.Url, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonMscrm? FromApi(ClientAddonMscrm? source) => source is null ? null : new() + { + Url = source.Url, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonSlack? FromApi(ClientAddonSlack? source) => source is null ? null : new() + { + Team = source.Team, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonSentry? FromApi(ClientAddonSentry? source) => source is null ? null : new() + { + OrgSlug = source.OrgSlug, + BaseUrl = source.BaseUrl, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonEchoSign? FromApi(ClientAddonEchoSign? source) => source is null ? null : new() + { + Domain = source.Domain, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonEgnyte? FromApi(ClientAddonEgnyte? source) => source is null ? null : new() + { + Domain = source.Domain, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonFirebase? FromApi(ClientAddonFirebase? source) => source is null ? null : new() + { + Secret = source.Secret, + PrivateKeyId = source.PrivateKeyId, + PrivateKey = source.PrivateKey, + ClientEmail = source.ClientEmail, + LifetimeInSeconds = source.LifetimeInSeconds, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonNewRelic? FromApi(ClientAddonNewRelic? source) => source is null ? null : new() + { + Account = source.Account, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonOffice365? FromApi(ClientAddonOffice365? source) => source is null ? null : new() + { + Domain = source.Domain, + Connection = source.Connection, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonSalesforce? FromApi(ClientAddonSalesforce? source) => source is null ? null : new() + { + EntityId = source.EntityId, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonSalesforceApi? FromApi(ClientAddonSalesforceApi? source) => source is null ? null : new() + { + Clientid = source.Clientid, + Principal = source.Principal, + CommunityName = source.CommunityName, + CommunityUrlSection = source.CommunityUrlSection, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonSalesforceSandboxApi? FromApi(ClientAddonSalesforceSandboxApi? source) => source is null ? null : new() + { + Clientid = source.Clientid, + Principal = source.Principal, + CommunityName = source.CommunityName, + CommunityUrlSection = source.CommunityUrlSection, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonSaml? FromApi(ClientAddonSaml? source) => source is null ? null : new() + { + Mappings = source.Mappings, + Audience = source.Audience, + Recipient = source.Recipient, + CreateUpnClaim = source.CreateUpnClaim, + MapUnknownClaimsAsIs = source.MapUnknownClaimsAsIs, + PassthroughClaimsWithNoMapping = source.PassthroughClaimsWithNoMapping, + MapIdentities = source.MapIdentities, + SignatureAlgorithm = source.SignatureAlgorithm, + DigestAlgorithm = source.DigestAlgorithm, + Issuer = source.Issuer, + Destination = source.Destination, + LifetimeInSeconds = source.LifetimeInSeconds, + SignResponse = source.SignResponse, + NameIdentifierFormat = source.NameIdentifierFormat, + NameIdentifierProbes = source.NameIdentifierProbes?.ToArray(), + AuthnContextClassRef = source.AuthnContextClassRef, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonLayer? FromApi(ClientAddonLayer? source) => source is null ? null : new() + { + ProviderId = source.ProviderId, + KeyId = source.KeyId, + PrivateKey = source.PrivateKey, + Principal = source.Principal, + Expiration = source.Expiration, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonSapapi? FromApi(ClientAddonSapapi? source) => source is null ? null : new() + { + Clientid = source.Clientid, + UsernameAttribute = source.UsernameAttribute, + TokenEndpointUrl = source.TokenEndpointUrl, + Scope = source.Scope, + ServicePassword = source.ServicePassword, + NameIdentifierFormat = source.NameIdentifierFormat, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonSharePoint? FromApi(ClientAddonSharePoint? source) => source is null ? null : new() + { + Url = source.Url, + ExternalUrl = source.ExternalUrl is { } externalUrl ? FromApi(externalUrl) : null, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static string[]? FromApi(ClientAddonSharePointExternalUrl? source) + { + if (source is null) + return null; + + if (source.TryGetListOfString(out var values)) + return values?.ToArray(); + + if (source.TryGetString(out var value)) + return value is null ? null : [value]; + + throw new NotImplementedException(); + } + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonSpringCm? FromApi(ClientAddonSpringCm? source) => source is null ? null : new() + { + Acsurl = source.Acsurl, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonWams? FromApi(ClientAddonWams? source) => source is null ? null : new() + { + Masterkey = source.Masterkey, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonZendesk? FromApi(ClientAddonZendesk? source) => source is null ? null : new() + { + AccountName = source.AccountName, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonZoom? FromApi(ClientAddonZoom? source) => source is null ? null : new() + { + Account = source.Account, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonSsoIntegration? FromApi(ClientAddonSsoIntegration? source) => source is null ? null : new() + { + Name = source.Name, + Version = source.Version, + }; + + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ClientAddonOag? FromApi(ClientAddonOag? source) => source is null ? null : new(); + + internal static ClientTokenEndpointAuthMethodEnum ToApi(V2alpha1ClientTokenEndpointAuthMethodEnum source) => source switch + { + V2alpha1ClientTokenEndpointAuthMethodEnum.None => new ClientTokenEndpointAuthMethodEnum(ClientTokenEndpointAuthMethodEnum.Values.None), + V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretPost => new ClientTokenEndpointAuthMethodEnum(ClientTokenEndpointAuthMethodEnum.Values.ClientSecretPost), + V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretBasic => new ClientTokenEndpointAuthMethodEnum(ClientTokenEndpointAuthMethodEnum.Values.ClientSecretBasic), + _ => throw new NotImplementedException(), + }; + + internal static ClientTokenEndpointAuthMethodOrNullEnum ToApiOrNull(V2alpha1ClientTokenEndpointAuthMethodEnum source) => source switch + { + V2alpha1ClientTokenEndpointAuthMethodEnum.None => new ClientTokenEndpointAuthMethodOrNullEnum(ClientTokenEndpointAuthMethodOrNullEnum.Values.None), + V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretPost => new ClientTokenEndpointAuthMethodOrNullEnum(ClientTokenEndpointAuthMethodOrNullEnum.Values.ClientSecretPost), + V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretBasic => new ClientTokenEndpointAuthMethodOrNullEnum(ClientTokenEndpointAuthMethodOrNullEnum.Values.ClientSecretBasic), + _ => throw new NotImplementedException(), + }; + + internal static ClientAppTypeEnum ToApi(V2alpha1ClientAppTypeEnum source) => source switch + { + V2alpha1ClientAppTypeEnum.Box => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Box), + V2alpha1ClientAppTypeEnum.Cloudbees => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Cloudbees), + V2alpha1ClientAppTypeEnum.Concur => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Concur), + V2alpha1ClientAppTypeEnum.Dropbox => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Dropbox), + V2alpha1ClientAppTypeEnum.Echosign => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Echosign), + V2alpha1ClientAppTypeEnum.Egnyte => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Egnyte), + V2alpha1ClientAppTypeEnum.Mscrm => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Mscrm), + V2alpha1ClientAppTypeEnum.Native => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Native), + V2alpha1ClientAppTypeEnum.Newrelic => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Newrelic), + V2alpha1ClientAppTypeEnum.NonInteractive => new ClientAppTypeEnum(ClientAppTypeEnum.Values.NonInteractive), + V2alpha1ClientAppTypeEnum.Office365 => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Office365), + V2alpha1ClientAppTypeEnum.RegularWeb => new ClientAppTypeEnum(ClientAppTypeEnum.Values.RegularWeb), + V2alpha1ClientAppTypeEnum.Rms => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Rms), + V2alpha1ClientAppTypeEnum.Salesforce => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Salesforce), + V2alpha1ClientAppTypeEnum.Sentry => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Sentry), + V2alpha1ClientAppTypeEnum.Sharepoint => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Sharepoint), + V2alpha1ClientAppTypeEnum.Slack => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Slack), + V2alpha1ClientAppTypeEnum.Springcm => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Springcm), + V2alpha1ClientAppTypeEnum.Spa => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Spa), + V2alpha1ClientAppTypeEnum.Zendesk => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Zendesk), + V2alpha1ClientAppTypeEnum.Zoom => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Zoom), + V2alpha1ClientAppTypeEnum.ResourceServer => new ClientAppTypeEnum(ClientAppTypeEnum.Values.ResourceServer), + V2alpha1ClientAppTypeEnum.ExpressConfiguration => new ClientAppTypeEnum(ClientAppTypeEnum.Values.ExpressConfiguration), + V2alpha1ClientAppTypeEnum.SsoIntegration => new ClientAppTypeEnum(ClientAppTypeEnum.Values.SsoIntegration), + V2alpha1ClientAppTypeEnum.Oag => new ClientAppTypeEnum(ClientAppTypeEnum.Values.Oag), + _ => throw new NotImplementedException(), + }; + + internal static SigningAlgorithmEnum ToApi(V2alpha1ClientSigningAlgorithmEnum source) => source switch + { + V2alpha1ClientSigningAlgorithmEnum.Hs256 => new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Hs256), + V2alpha1ClientSigningAlgorithmEnum.Rs256 => new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Rs256), + V2alpha1ClientSigningAlgorithmEnum.Rs512 => new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Rs512), + V2alpha1ClientSigningAlgorithmEnum.Ps256 => new SigningAlgorithmEnum(SigningAlgorithmEnum.Values.Ps256), + _ => throw new NotImplementedException(), + }; + + internal static ClientComplianceLevelEnum ToApi(V2alpha1ClientComplianceLevelEnum source) => source switch + { + V2alpha1ClientComplianceLevelEnum.None => new ClientComplianceLevelEnum(ClientComplianceLevelEnum.Values.None), + V2alpha1ClientComplianceLevelEnum.Fapi1AdvPkjPar => new ClientComplianceLevelEnum(ClientComplianceLevelEnum.Values.Fapi1AdvPkjPar), + V2alpha1ClientComplianceLevelEnum.Fapi1AdvMtlsPar => new ClientComplianceLevelEnum(ClientComplianceLevelEnum.Values.Fapi1AdvMtlsPar), + V2alpha1ClientComplianceLevelEnum.Fapi2SpPkjMtls => new ClientComplianceLevelEnum(ClientComplianceLevelEnum.Values.Fapi2SpPkjMtls), + V2alpha1ClientComplianceLevelEnum.Fapi2SpMtlsMtls => new ClientComplianceLevelEnum(ClientComplianceLevelEnum.Values.Fapi2SpMtlsMtls), + _ => throw new NotImplementedException(), + }; + + internal static ClientOrganizationRequireBehaviorEnum ToApi(V2alpha1ClientOrganizationRequireBehaviorEnum source) => source switch + { + V2alpha1ClientOrganizationRequireBehaviorEnum.NoPrompt => new ClientOrganizationRequireBehaviorEnum(ClientOrganizationRequireBehaviorEnum.Values.NoPrompt), + V2alpha1ClientOrganizationRequireBehaviorEnum.PreLoginPrompt => new ClientOrganizationRequireBehaviorEnum(ClientOrganizationRequireBehaviorEnum.Values.PreLoginPrompt), + V2alpha1ClientOrganizationRequireBehaviorEnum.PostLoginPrompt => new ClientOrganizationRequireBehaviorEnum(ClientOrganizationRequireBehaviorEnum.Values.PostLoginPrompt), + _ => throw new NotImplementedException(), + }; + + internal static ClientOrganizationRequireBehaviorPatchEnum ToApiPatch(V2alpha1ClientOrganizationRequireBehaviorEnum source) => source switch + { + V2alpha1ClientOrganizationRequireBehaviorEnum.NoPrompt => new ClientOrganizationRequireBehaviorPatchEnum(ClientOrganizationRequireBehaviorPatchEnum.Values.NoPrompt), + V2alpha1ClientOrganizationRequireBehaviorEnum.PreLoginPrompt => new ClientOrganizationRequireBehaviorPatchEnum(ClientOrganizationRequireBehaviorPatchEnum.Values.PreLoginPrompt), + V2alpha1ClientOrganizationRequireBehaviorEnum.PostLoginPrompt => new ClientOrganizationRequireBehaviorPatchEnum(ClientOrganizationRequireBehaviorPatchEnum.Values.PostLoginPrompt), + _ => throw new NotImplementedException(), + }; + + internal static ClientOrganizationUsageEnum ToApi(V2alpha1ClientOrganizationUsageEnum source) => source switch + { + V2alpha1ClientOrganizationUsageEnum.Deny => new ClientOrganizationUsageEnum(ClientOrganizationUsageEnum.Values.Deny), + V2alpha1ClientOrganizationUsageEnum.Allow => new ClientOrganizationUsageEnum(ClientOrganizationUsageEnum.Values.Allow), + V2alpha1ClientOrganizationUsageEnum.Require => new ClientOrganizationUsageEnum(ClientOrganizationUsageEnum.Values.Require), + _ => throw new NotImplementedException(), + }; + + internal static ClientOrganizationUsagePatchEnum ToApiPatch(V2alpha1ClientOrganizationUsageEnum source) => source switch + { + V2alpha1ClientOrganizationUsageEnum.Deny => new ClientOrganizationUsagePatchEnum(ClientOrganizationUsagePatchEnum.Values.Deny), + V2alpha1ClientOrganizationUsageEnum.Allow => new ClientOrganizationUsagePatchEnum(ClientOrganizationUsagePatchEnum.Values.Allow), + V2alpha1ClientOrganizationUsageEnum.Require => new ClientOrganizationUsagePatchEnum(ClientOrganizationUsagePatchEnum.Values.Require), + _ => throw new NotImplementedException(), + }; + + internal static RefreshTokenRotationTypeEnum ToApi(V2alpha1ClientRefreshTokenRotationTypeEnum source) => source switch + { + V2alpha1ClientRefreshTokenRotationTypeEnum.Rotating => new RefreshTokenRotationTypeEnum(RefreshTokenRotationTypeEnum.Values.Rotating), + V2alpha1ClientRefreshTokenRotationTypeEnum.NonRotating => new RefreshTokenRotationTypeEnum(RefreshTokenRotationTypeEnum.Values.NonRotating), + _ => throw new NotImplementedException(), + }; + + internal static RefreshTokenExpirationTypeEnum ToApi(V2alpha1ClientRefreshTokenExpirationTypeEnum source) => source switch + { + V2alpha1ClientRefreshTokenExpirationTypeEnum.Expiring => new RefreshTokenExpirationTypeEnum(RefreshTokenExpirationTypeEnum.Values.Expiring), + V2alpha1ClientRefreshTokenExpirationTypeEnum.NonExpiring => new RefreshTokenExpirationTypeEnum(RefreshTokenExpirationTypeEnum.Values.NonExpiring), + _ => throw new NotImplementedException(), + }; + + internal static ClientOidcBackchannelLogoutInitiatorsModeEnum ToApi(V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum source) => source switch + { + V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.All => new ClientOidcBackchannelLogoutInitiatorsModeEnum(ClientOidcBackchannelLogoutInitiatorsModeEnum.Values.All), + V2alpha1ClientOidcBackchannelLogoutInitiatorsModeEnum.Custom => new ClientOidcBackchannelLogoutInitiatorsModeEnum(ClientOidcBackchannelLogoutInitiatorsModeEnum.Values.Custom), + _ => throw new NotImplementedException(), + }; + + internal static ClientOidcBackchannelLogoutInitiatorsEnum ToApi(V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum source) => source switch + { + V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.RpLogout => new ClientOidcBackchannelLogoutInitiatorsEnum(ClientOidcBackchannelLogoutInitiatorsEnum.Values.RpLogout), + V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.IdpLogout => new ClientOidcBackchannelLogoutInitiatorsEnum(ClientOidcBackchannelLogoutInitiatorsEnum.Values.IdpLogout), + V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.PasswordChanged => new ClientOidcBackchannelLogoutInitiatorsEnum(ClientOidcBackchannelLogoutInitiatorsEnum.Values.PasswordChanged), + V2alpha1ClientOidcBackchannelLogoutInitiatorsEnum.SessionExpired => new ClientOidcBackchannelLogoutInitiatorsEnum(ClientOidcBackchannelLogoutInitiatorsEnum.Values.SessionExpired), + _ => throw new NotImplementedException(), + }; + + static ClientOidcBackchannelLogoutSessionMetadata ToApi(V2alpha1ClientOidcBackchannelLogoutSessionMetadata source) => new() + { + Include = source.Include, + }; + + static ClientDefaultOrganization ToApi(V2alpha1ClientDefaultOrganization source) => new() + { + OrganizationId = source.OrganizationId, + Flows = source.Flows?.Select(ToApi).ToArray(), + }; + + static ClientDefaultOrganizationFlowsEnum ToApi(V2alpha1ClientDefaultOrganizationFlowsEnum source) => source switch + { + V2alpha1ClientDefaultOrganizationFlowsEnum.ClientCredentials => new ClientDefaultOrganizationFlowsEnum(ClientDefaultOrganizationFlowsEnum.Values.ClientCredentials), + _ => throw new NotImplementedException(), + }; + + internal static ClientAddons ToApi(V2alpha1ClientAddons source) => new() + { + Aws = source.Aws is { } aws ? ToApi(aws) : null, + AzureBlob = source.AzureBlob is { } azureBlob ? ToApi(azureBlob) : null, + AzureSb = source.AzureSb is { } azureSb ? ToApi(azureSb) : null, + Rms = source.Rms is { } rms ? ToApi(rms) : null, + Mscrm = source.Mscrm is { } mscrm ? ToApi(mscrm) : null, + Slack = source.Slack is { } slack ? ToApi(slack) : null, + Sentry = source.Sentry is { } sentry ? ToApi(sentry) : null, + Box = source.Box, + Cloudbees = source.Cloudbees, + Concur = source.Concur, + Dropbox = source.Dropbox, + Echosign = source.Echosign is { } echosign ? ToApi(echosign) : null, + Egnyte = source.Egnyte is { } egnyte ? ToApi(egnyte) : null, + Firebase = source.Firebase is { } firebase ? ToApi(firebase) : null, + Newrelic = source.Newrelic is { } newrelic ? ToApi(newrelic) : null, + Office365 = source.Office365 is { } office365 ? ToApi(office365) : null, + Salesforce = source.Salesforce is { } salesforce ? ToApi(salesforce) : null, + SalesforceApi = source.SalesforceApi is { } salesforceApi ? ToApi(salesforceApi) : null, + SalesforceSandboxApi = source.SalesforceSandboxApi is { } salesforceSandboxApi ? ToApi(salesforceSandboxApi) : null, + Samlp = source.Samlp is { } samlp ? ToApi(samlp) : null, + Layer = source.Layer is { } layer ? ToApi(layer) : null, + SapApi = source.SapApi is { } sapApi ? ToApi(sapApi) : null, + Sharepoint = source.Sharepoint is { } sharepoint ? ToApi(sharepoint) : null, + Springcm = source.Springcm is { } springcm ? ToApi(springcm) : null, + Wams = source.Wams is { } wams ? ToApi(wams) : null, + Wsfed = source.Wsfed, + Zendesk = source.Zendesk is { } zendesk ? ToApi(zendesk) : null, + Zoom = source.Zoom is { } zoom ? ToApi(zoom) : null, + SsoIntegration = source.SsoIntegration is { } ssoIntegration ? ToApi(ssoIntegration) : null, + Oag = source.Oag is { } oag ? ToApi(oag) : null, + }; + + static ClientAddonAws ToApi(V2alpha1ClientAddonAws source) => new() + { + Principal = source.Principal, + Role = source.Role, + LifetimeInSeconds = source.LifetimeInSeconds, + }; + + static ClientAddonAzureBlob ToApi(V2alpha1ClientAddonAzureBlob source) => new() + { + AccountName = source.AccountName, + StorageAccessKey = source.StorageAccessKey, + ContainerName = source.ContainerName, + BlobName = source.BlobName, + Expiration = source.Expiration, + SignedIdentifier = source.SignedIdentifier, + BlobRead = source.BlobRead, + BlobWrite = source.BlobWrite, + BlobDelete = source.BlobDelete, + ContainerRead = source.ContainerRead, + ContainerWrite = source.ContainerWrite, + ContainerDelete = source.ContainerDelete, + ContainerList = source.ContainerList, + }; + + static ClientAddonAzureSb ToApi(V2alpha1ClientAddonAzureSb source) => new() + { + Namespace = source.Namespace, + SasKeyName = source.SasKeyName, + SasKey = source.SasKey, + EntityPath = source.EntityPath, + Expiration = source.Expiration, + }; + + static ClientAddonRms ToApi(V2alpha1ClientAddonRms source) => new() + { + Url = source.Url, + }; + + static ClientAddonMscrm ToApi(V2alpha1ClientAddonMscrm source) => new() + { + Url = source.Url, + }; + + static ClientAddonSlack ToApi(V2alpha1ClientAddonSlack source) => new() + { + Team = source.Team, + }; + + static ClientAddonSentry ToApi(V2alpha1ClientAddonSentry source) => new() + { + OrgSlug = source.OrgSlug, + BaseUrl = source.BaseUrl, + }; + + static ClientAddonEchoSign ToApi(V2alpha1ClientAddonEchoSign source) => new() + { + Domain = source.Domain, + }; + + static ClientAddonEgnyte ToApi(V2alpha1ClientAddonEgnyte source) => new() + { + Domain = source.Domain, + }; + + static ClientAddonFirebase ToApi(V2alpha1ClientAddonFirebase source) => new() + { + Secret = source.Secret, + PrivateKeyId = source.PrivateKeyId, + PrivateKey = source.PrivateKey, + ClientEmail = source.ClientEmail, + LifetimeInSeconds = source.LifetimeInSeconds, + }; + + static ClientAddonNewRelic ToApi(V2alpha1ClientAddonNewRelic source) => new() + { + Account = source.Account, + }; + + static ClientAddonOffice365 ToApi(V2alpha1ClientAddonOffice365 source) => new() + { + Domain = source.Domain, + Connection = source.Connection, + }; + + static ClientAddonSalesforce ToApi(V2alpha1ClientAddonSalesforce source) => new() + { + EntityId = source.EntityId, + }; + + static ClientAddonSalesforceApi ToApi(V2alpha1ClientAddonSalesforceApi source) => new() + { + Clientid = source.Clientid, + Principal = source.Principal, + CommunityName = source.CommunityName, + CommunityUrlSection = source.CommunityUrlSection, + }; + + static ClientAddonSalesforceSandboxApi ToApi(V2alpha1ClientAddonSalesforceSandboxApi source) => new() + { + Clientid = source.Clientid, + Principal = source.Principal, + CommunityName = source.CommunityName, + CommunityUrlSection = source.CommunityUrlSection, + }; + + static ClientAddonSaml ToApi(V2alpha1ClientAddonSaml source) => new() + { + Mappings = source.Mappings, + Audience = source.Audience, + Recipient = source.Recipient, + CreateUpnClaim = source.CreateUpnClaim, + MapUnknownClaimsAsIs = source.MapUnknownClaimsAsIs, + PassthroughClaimsWithNoMapping = source.PassthroughClaimsWithNoMapping, + MapIdentities = source.MapIdentities, + SignatureAlgorithm = source.SignatureAlgorithm, + DigestAlgorithm = source.DigestAlgorithm, + Issuer = source.Issuer, + Destination = source.Destination, + LifetimeInSeconds = source.LifetimeInSeconds, + SignResponse = source.SignResponse, + NameIdentifierFormat = source.NameIdentifierFormat, + NameIdentifierProbes = source.NameIdentifierProbes, + AuthnContextClassRef = source.AuthnContextClassRef, + }; + + static ClientAddonLayer ToApi(V2alpha1ClientAddonLayer source) => new() + { + ProviderId = source.ProviderId, + KeyId = source.KeyId, + PrivateKey = source.PrivateKey, + Principal = source.Principal, + Expiration = source.Expiration, + }; + + static ClientAddonSapapi ToApi(V2alpha1ClientAddonSapapi source) => new() + { + Clientid = source.Clientid, + UsernameAttribute = source.UsernameAttribute, + TokenEndpointUrl = source.TokenEndpointUrl, + Scope = source.Scope, + ServicePassword = source.ServicePassword, + NameIdentifierFormat = source.NameIdentifierFormat, + }; + + static ClientAddonSharePoint ToApi(V2alpha1ClientAddonSharePoint source) + { + var target = new ClientAddonSharePoint + { + Url = source.Url, + }; + + if (source.ExternalUrl is not null) + { + target.ExternalUrl = ToApi(source.ExternalUrl); + } + + return target; + } + + static ClientAddonSharePointExternalUrl ToApi(string[] source) + { + return ClientAddonSharePointExternalUrl.FromListOfString(source); + } + + static ClientAddonSpringCm ToApi(V2alpha1ClientAddonSpringCm source) => new() + { + Acsurl = source.Acsurl, + }; + + static ClientAddonWams ToApi(V2alpha1ClientAddonWams source) => new() + { + Masterkey = source.Masterkey, + }; + + static ClientAddonZendesk ToApi(V2alpha1ClientAddonZendesk source) => new() + { + AccountName = source.AccountName, + }; + + static ClientAddonZoom ToApi(V2alpha1ClientAddonZoom source) => new() + { + Account = source.Account, + }; + + static ClientAddonSsoIntegration ToApi(V2alpha1ClientAddonSsoIntegration source) => new() + { + Name = source.Name, + Version = source.Version, + }; + + static ClientAddonOag ToApi(V2alpha1ClientAddonOag source) => new(); + + internal static void ApplyToApi(V2alpha1ClientRefreshTokenConfiguration source, ClientRefreshTokenConfiguration target) + { + if (source.RotationType is { } rotationType) + target.RotationType = ToApi(rotationType); + + if (source.ExpirationType is { } expirationType) + target.ExpirationType = ToApi(expirationType); + + if (source.Leeway is { } leeway) + target.Leeway = leeway; + + if (source.TokenLifetime is { } tokenLifetime) + target.TokenLifetime = tokenLifetime; + + if (source.InfiniteTokenLifetime is { } infiniteTokenLifetime) + target.InfiniteTokenLifetime = infiniteTokenLifetime; + + if (source.IdleTokenLifetime is { } idleTokenLifetime) + target.IdleTokenLifetime = idleTokenLifetime; + + if (source.InfiniteIdleTokenLifetime is { } infiniteIdleTokenLifetime) + target.InfiniteIdleTokenLifetime = infiniteIdleTokenLifetime; + } + + internal static void ApplyToApi(V2alpha1ClientOidcBackchannelLogoutInitiators source, ClientOidcBackchannelLogoutInitiators target) + { + if (source.Mode is { } mode) + target.Mode = ToApi(mode); + + if (source.SelectedInitiators is { } selected) + target.SelectedInitiators = [.. selected.Select(ToApi)]; + } + + internal static void ApplyToApi(V2alpha1ClientOidcBackchannelLogoutSettings source, ClientOidcBackchannelLogoutSettings target) + { + if (source.BackchannelLogoutUrls is { } backchannelLogoutUrls) + target.BackchannelLogoutUrls = backchannelLogoutUrls; + + if (source.BackchannelLogoutInitiators is { } initiators) + ApplyToApi(initiators, target.BackchannelLogoutInitiators ??= new()); + + if (source.BackchannelLogoutSessionMetadata is { } sessionMetadata) + target.BackchannelLogoutSessionMetadata = ToApi(sessionMetadata); + } + + internal static void ApplyToApi(V2alpha1ClientEncryptionKey source, ClientEncryptionKey target) + { + if (source.Cert is { } cert) + target.Cert = cert; + + if (source.Pub is { } pub) + target.Pub = pub; + + if (source.Subject is { } subject) + target.Subject = subject; + } + + internal static void ApplyToApi(V2alpha1ClientJwtConfiguration source, ClientJwtConfiguration target) + { + if (source.SecretEncoded is { } secretEncoded) + target.SecretEncoded = secretEncoded; + + if (source.LifetimeInSeconds is { } lifetimeInSeconds) + target.LifetimeInSeconds = lifetimeInSeconds; + + if (source.Alg is { } alg) + target.Alg = ToApi(alg); + + if (source.Scopes is { } scopes) + target.Scopes = scopes; + } + + internal static void ApplyToApi(V2alpha1ClientMobileAndroid source, ClientMobileAndroid target) + { + if (source.AppPackageName is { } appPackageName) + target.AppPackageName = appPackageName; + } + + internal static void ApplyToApi(V2alpha1ClientMobileiOs source, ClientMobileiOs target) + { + if (source.AppBundleIdentifier is { } appBundleIdentifier) + target.AppBundleIdentifier = appBundleIdentifier; + + if (source.TeamId is { } teamId) + target.TeamId = teamId; + } + + internal static void ApplyToApi(V2alpha1ClientMobile source, ClientMobile target) + { + if (source.Android is { } android && android.AppPackageName is not null) + ApplyToApi(android, target.Android ??= new ClientMobileAndroid()); + + if (source.Ios is { } ios && (ios.AppBundleIdentifier is not null || ios.TeamId is not null)) + ApplyToApi(ios, target.Ios ??= new ClientMobileiOs()); + } + + internal static void ApplyToApi(V2alpha1ClientConf conf, CreateClientRequestContent request) + { + if (conf.ApplicationType is { } appType) + request.AppType = ToApi(appType); + + if (conf.TokenEndpointAuthMethod is { } tokenEndpointAuthMethod) + request.TokenEndpointAuthMethod = ToApi(tokenEndpointAuthMethod); + + ApplyToApiBase(conf, request); + } + + internal static void ApplyToApi(V2alpha1ClientConf conf, UpdateClientRequestContent request) + { + if (conf.ApplicationType is { } appType) + request.AppType = ToApi(appType); + + if (conf.TokenEndpointAuthMethod is { } tokenEndpointAuthMethod) + request.TokenEndpointAuthMethod = ToApiOrNull(tokenEndpointAuthMethod); + + ApplyToApiBase(conf, request); + } + + internal static void ApplyToApiBase(V2alpha1ClientConf conf, CreateClientRequestContent request) + { + if (conf.AddOns is { } addons) + request.Addons = ToApi(addons); + + if (conf.AllowedClients is not null) + request.AllowedClients = conf.AllowedClients; + + if (conf.AllowedLogoutUrls is not null) + request.AllowedLogoutUrls = conf.AllowedLogoutUrls; + + if (conf.AllowedOrigins is not null) + request.AllowedOrigins = conf.AllowedOrigins; + + if (conf.WebOrigins is not null) + request.WebOrigins = conf.WebOrigins; + + if (conf.InitiateLoginUri is not null) + request.InitiateLoginUri = conf.InitiateLoginUri; + + if (conf.Callbacks is not null) + request.Callbacks = conf.Callbacks; + + if (conf.ClientAliases is not null) + request.ClientAliases = conf.ClientAliases; + + if (conf.ClientMetaData is not null) + request.ClientMetadata = conf.ClientMetaData; + + if (conf.IsCustomLoginPageOn is not null) + request.CustomLoginPageOn = conf.IsCustomLoginPageOn; + + if (conf.IsFirstParty is not null) + request.IsFirstParty = conf.IsFirstParty; + + if (conf.CustomLoginPage is not null) + request.CustomLoginPage = conf.CustomLoginPage; + + if (conf.CustomLoginPagePreview is not null) + request.CustomLoginPagePreview = conf.CustomLoginPagePreview; + + if (conf.EncryptionKey is { } encryptionKey) + { + var target = new ClientEncryptionKey(); + ApplyToApi(encryptionKey, target); + request.EncryptionKey = target; + } + + if (conf.FormTemplate is not null) + request.FormTemplate = conf.FormTemplate; + + if (conf.GrantTypes is not null) + request.GrantTypes = conf.GrantTypes.Distinct().ToArray(); + + if (conf.JwtConfiguration is { } jwtConfiguration) + ApplyToApi(jwtConfiguration, request.JwtConfiguration ??= new()); + + if (conf.Mobile is { } mobile) + { + var target = new ClientMobile(); + ApplyToApi(mobile, target); + if (target.Android is not null || target.Ios is not null) + request.Mobile = target; + } + + if (conf.Name is not null) + request.Name = conf.Name; + + if (conf.Description is not null) + request.Description = conf.Description; + + if (conf.LogoUri is not null) + request.LogoUri = conf.LogoUri; + + if (conf.OidcConformant is not null) + request.OidcConformant = conf.OidcConformant; + + if (conf.OidcLogout is { } oidcLogout) + ApplyToApi(oidcLogout, request.OidcLogout ??= new()); + + if (conf.Sso is not null) + request.Sso = conf.Sso; + + if (conf.RefreshToken is { } refreshToken) + { + var target = new ClientRefreshTokenConfiguration + { + RotationType = refreshToken.RotationType is { } rotationType ? ToApi(rotationType) : new RefreshTokenRotationTypeEnum(RefreshTokenRotationTypeEnum.Values.NonRotating), + ExpirationType = refreshToken.ExpirationType is { } expirationType ? ToApi(expirationType) : new RefreshTokenExpirationTypeEnum(RefreshTokenExpirationTypeEnum.Values.NonExpiring), + }; + ApplyToApi(refreshToken, target); + request.RefreshToken = target; + } + + if (conf.OrganizationUsage is { } organizationUsage) + request.OrganizationUsage = ToApi(organizationUsage); + + if (conf.OrganizationRequireBehavior is { } organizationRequireBehavior) + request.OrganizationRequireBehavior = ToApi(organizationRequireBehavior); + + if (conf.CrossOriginAuthentication is not null) + request.CrossOriginAuthentication = conf.CrossOriginAuthentication; + + if (conf.RequirePushedAuthorizationRequests is not null) + request.RequirePushedAuthorizationRequests = conf.RequirePushedAuthorizationRequests; + + if (conf.DefaultOrganization is { } defaultOrganization) + request.DefaultOrganization = ToApi(defaultOrganization); + + if (conf.ComplianceLevel is { } complianceLevel) + request.ComplianceLevel = ToApi(complianceLevel); + + if (conf.RequireProofOfPossession is not null) + request.RequireProofOfPossession = conf.RequireProofOfPossession; + } + + internal static void ApplyToApiBase(V2alpha1ClientConf conf, UpdateClientRequestContent request) + { + if (conf.AddOns is { } addons) + request.Addons = ToApi(addons); + + if (conf.AllowedClients is not null) + request.AllowedClients = conf.AllowedClients; + + if (conf.AllowedLogoutUrls is not null) + request.AllowedLogoutUrls = conf.AllowedLogoutUrls; + + if (conf.AllowedOrigins is not null) + request.AllowedOrigins = conf.AllowedOrigins; + + if (conf.WebOrigins is not null) + request.WebOrigins = conf.WebOrigins; + + if (conf.InitiateLoginUri is not null) + request.InitiateLoginUri = conf.InitiateLoginUri; + + if (conf.Callbacks is not null) + request.Callbacks = conf.Callbacks; + + if (conf.ClientAliases is not null) + request.ClientAliases = conf.ClientAliases; + + if (conf.ClientMetaData is not null) + request.ClientMetadata = conf.ClientMetaData; + + if (conf.IsCustomLoginPageOn is not null) + request.CustomLoginPageOn = conf.IsCustomLoginPageOn; + + if (conf.IsFirstParty is not null) + request.IsFirstParty = conf.IsFirstParty; + + if (conf.CustomLoginPage is not null) + request.CustomLoginPage = conf.CustomLoginPage; + + if (conf.CustomLoginPagePreview is not null) + request.CustomLoginPagePreview = conf.CustomLoginPagePreview; + + if (conf.EncryptionKey is { } encryptionKey) + { + var target = new ClientEncryptionKey(); + ApplyToApi(encryptionKey, target); + request.EncryptionKey = target; + } + + if (conf.FormTemplate is not null) + request.FormTemplate = conf.FormTemplate; + + if (conf.GrantTypes is not null) + request.GrantTypes = conf.GrantTypes.Distinct().ToArray(); + + if (conf.JwtConfiguration is { } jwtConfiguration) + ApplyToApi(jwtConfiguration, request.JwtConfiguration ??= new()); + + if (conf.Mobile is { } mobile) + { + var target = new ClientMobile(); + ApplyToApi(mobile, target); + if (target.Android is not null || target.Ios is not null) + request.Mobile = target; + } + + if (conf.Name is not null) + request.Name = conf.Name; + + if (conf.Description is not null) + request.Description = conf.Description; + + if (conf.LogoUri is not null) + request.LogoUri = conf.LogoUri; + + if (conf.OidcConformant is not null) + request.OidcConformant = conf.OidcConformant; + + if (conf.OidcLogout is { } oidcLogout) + ApplyToApi(oidcLogout, request.OidcLogout ??= new()); + + if (conf.Sso is not null) + request.Sso = conf.Sso; + + if (conf.RefreshToken is { } refreshToken) + { + var target = new ClientRefreshTokenConfiguration + { + RotationType = refreshToken.RotationType is { } rotationType ? ToApi(rotationType) : new RefreshTokenRotationTypeEnum(RefreshTokenRotationTypeEnum.Values.NonRotating), + ExpirationType = refreshToken.ExpirationType is { } expirationType ? ToApi(expirationType) : new RefreshTokenExpirationTypeEnum(RefreshTokenExpirationTypeEnum.Values.NonExpiring), + }; + ApplyToApi(refreshToken, target); + request.RefreshToken = target; + } + + if (conf.OrganizationUsage is { } organizationUsage) + request.OrganizationUsage = ToApiPatch(organizationUsage); + + if (conf.OrganizationRequireBehavior is { } organizationRequireBehavior) + request.OrganizationRequireBehavior = ToApiPatch(organizationRequireBehavior); + + if (conf.CrossOriginAuthentication is not null) + request.CrossOriginAuthentication = conf.CrossOriginAuthentication; + + if (conf.RequirePushedAuthorizationRequests is not null) + request.RequirePushedAuthorizationRequests = conf.RequirePushedAuthorizationRequests; + + if (conf.DefaultOrganization is { } defaultOrganization) + request.DefaultOrganization = ToApi(defaultOrganization); + + if (conf.ComplianceLevel is { } complianceLevel) + request.ComplianceLevel = ToApi(complianceLevel); + + if (conf.RequireProofOfPossession is not null) + request.RequireProofOfPossession = conf.RequireProofOfPossession; + } + + public V2alpha1ClientController(IKubernetesClient kube, IMemoryCache cache, IOptions options, ILogger logger) : + base(kube, cache, options, logger) + { + } + + protected override string EntityTypeName => "Client"; + + protected override async Task Get(IManagementApiClient api, string id, string defaultNamespace, CancellationToken cancellationToken) + { + try + { + return FromApi(await api.Clients.GetAsync(id, new GetClientRequestParameters(), null, cancellationToken)); + } + catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) + { + return null; + } + } + + protected override async Task Find(IManagementApiClient api, V2alpha1Client entity, V2alpha1Client.SpecDef spec, string defaultNamespace, CancellationToken cancellationToken) + { + if (spec.Find is not null) + { + if (spec.Find.ClientId is string clientId) + { + try + { + var client = await api.Clients.GetAsync(clientId, new GetClientRequestParameters { Fields = "client_id,name" }, null, cancellationToken); + Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} found existing client: {Name}", EntityTypeName, entity.Namespace(), entity.Name(), client.Name); + return client.ClientId; + } + catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) + { + Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} could not find client with id {ClientId}.", EntityTypeName, entity.Namespace(), entity.Name(), clientId); + } + } + + if (spec.Find.Name is string name) + { + var pager = await api.Clients.ListAsync(new ListClientsRequestParameters { Fields = "client_id,name" }, null, cancellationToken); + var self = pager.CurrentPage.Items.FirstOrDefault(i => i.Name == name); + return self?.ClientId; + } + } + else + { + var conf = spec.Init ?? spec.Conf; + if (conf is { Name: string name }) + { + var pager = await api.Clients.ListAsync(new ListClientsRequestParameters { Fields = "client_id,name" }, null, cancellationToken); + var self = pager.CurrentPage.Items.FirstOrDefault(i => i.Name == name); + return self?.ClientId; + } + } + + return null; + } + + protected override string? ValidateCreate(V2alpha1ClientConf conf) + { + if (conf.ApplicationType == null) + return "missing a value for application type"; + + return null; + } + + protected override async Task Create(IManagementApiClient api, V2alpha1ClientConf conf, string defaultNamespace, CancellationToken cancellationToken) + { + Logger.LogInformation("{EntityTypeName} creating client in Auth0 with name: {ClientName}", EntityTypeName, conf.Name); + + var req = new CreateClientRequestContent { Name = conf.Name ?? throw new InvalidOperationException("Missing client name.") }; + ApplyToApi(conf, req); + + var self = await api.Clients.CreateAsync(req, null, cancellationToken); + Logger.LogInformation("{EntityTypeName} successfully created client in Auth0 with ID: {ClientId} and name: {ClientName}", EntityTypeName, self.ClientId, conf.Name); + return self.ClientId; + } + + protected override async Task Update(IManagementApiClient api, string id, V2alpha1ClientConf? last, V2alpha1ClientConf conf, string defaultNamespace, CancellationToken cancellationToken) + { + Logger.LogInformation("{EntityTypeName} updating client in Auth0 with id: {ClientId} and name: {ClientName}", EntityTypeName, id, conf.Name); + + var req = new UpdateClientRequestContent(); + ApplyToApi(conf, req); + + if (last is not null && last.ClientMetaData != null && conf.ClientMetaData != null) + foreach (string key in last.ClientMetaData.Keys) + if (conf.ClientMetaData.ContainsKey(key) == false) + (req.ClientMetadata ??= new Dictionary())[key] = null; + + await api.Clients.UpdateAsync(id, req, null, cancellationToken); + Logger.LogInformation("{EntityTypeName} successfully updated client in Auth0 with id: {ClientId} and name: {ClientName}", EntityTypeName, id, conf.Name); + } + + protected override async Task ApplyStatus(IManagementApiClient api, V2alpha1Client entity, V2alpha1ClientConf lastConf, string defaultNamespace, CancellationToken cancellationToken) + { + if (entity.Spec.SecretRef is not null && entity.Status.Id is not null) + { + var client = await api.Clients.GetAsync(entity.Status.Id, new GetClientRequestParameters { Fields = "client_id,client_secret" }, null, cancellationToken); + await ApplySecret(entity, client.ClientId, client.ClientSecret, defaultNamespace, cancellationToken); + } + + await base.ApplyStatus(api, entity, lastConf, defaultNamespace, cancellationToken); + } + + async Task ApplySecret(V2alpha1Client entity, string? clientId, string? clientSecret, string defaultNamespace, CancellationToken cancellationToken) + { + if (entity.Spec.SecretRef is null) + return; + + var secret = await ResolveSecretRef(entity.Spec.SecretRef, entity.Spec.SecretRef.NamespaceProperty ?? defaultNamespace, cancellationToken); + if (secret is null) + { + Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} referenced secret {SecretName} which does not exist: creating.", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); + secret = await Kube.CreateAsync( + new V1Secret { Metadata = new V1ObjectMeta { NamespaceProperty = entity.Spec.SecretRef.NamespaceProperty ?? defaultNamespace, Name = entity.Spec.SecretRef.Name } } + .WithOwnerReference(entity), + cancellationToken); + } + + if (secret.IsOwnedBy(entity)) + { + Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} referenced secret {SecretName}: updating.", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); + secret.StringData ??= new Dictionary(); + + if (clientId is not null) + secret.StringData["clientId"] = clientId; + else if (!secret.StringData.ContainsKey("clientId")) + secret.StringData["clientId"] = ""; + + if (clientSecret is not null) + secret.StringData["clientSecret"] = clientSecret; + else if (!secret.StringData.ContainsKey("clientSecret")) + secret.StringData["clientSecret"] = ""; + + await Kube.UpdateAsync(secret, cancellationToken); + } + else + { + Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} secret {SecretName} exists but is not owned by this client, skipping update", EntityTypeName, entity.Namespace(), entity.Name(), entity.Spec.SecretRef.Name); + } + } + + protected override async Task DeletedAsync(IManagementApiClient api, string id, CancellationToken cancellationToken) + { + Logger.LogInformation("{EntityTypeName} deleting client from Auth0 with ID: {ClientId} (reason: Kubernetes entity deleted)", EntityTypeName, id); + await api.Clients.DeleteAsync(id, null, cancellationToken); + Logger.LogInformation("{EntityTypeName} successfully deleted client from Auth0 with ID: {ClientId}", EntityTypeName, id); + } + + } + +} diff --git a/src/Alethic.Auth0.Operator/Controllers/V2alpha1ConnectionController.cs b/src/Alethic.Auth0.Operator/Controllers/V2alpha1ConnectionController.cs new file mode 100644 index 0000000..fe3096d --- /dev/null +++ b/src/Alethic.Auth0.Operator/Controllers/V2alpha1ConnectionController.cs @@ -0,0 +1,4366 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; + +using Alethic.Auth0.Operator.Core.Models; +using Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; +using Alethic.Auth0.Operator.Models; +using Alethic.Auth0.Operator.Options; + +using Auth0.Core.Exceptions; +using Auth0.ManagementApi; +using Auth0.ManagementApi.Connections; +using Auth0.ManagementApi.Core; + +using k8s.Models; + +using KubeOps.Abstractions.Rbac; +using KubeOps.Abstractions.Reconciliation.Controller; +using KubeOps.KubernetesClient; + +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +using Newtonsoft.Json.Linq; + +namespace Alethic.Auth0.Operator.Controllers +{ + + [EntityRbac(typeof(V2alpha1Connection), Verbs = RbacVerb.All)] + [EntityRbac(typeof(V2alpha1Tenant), Verbs = RbacVerb.List | RbacVerb.Get)] + [EntityRbac(typeof(V1Secret), Verbs = RbacVerb.List | RbacVerb.Get)] + [EntityRbac(typeof(Eventsv1Event), Verbs = RbacVerb.All)] + public class V2alpha1ConnectionController : + V1TenantEntityInstanceController, + IEntityController + { + + /// + /// Initializes a new instance. + /// + /// + /// + /// + /// + public V2alpha1ConnectionController(IKubernetesClient kube, IMemoryCache cache, IOptions options, ILogger logger) : + base(kube, cache, options, logger) + { + + } + + /// + protected override string EntityTypeName => "Connection"; + + /// + /// + /// + /// + /// + /// + internal static TTo? JsonConvertTo(object? source) + { + return JsonSerializer.Deserialize(JsonSerializer.Serialize(source)); + } + + /// + /// Converts a API response to a . + /// Note: is populated separately and left null here. + /// + [return: NotNullIfNotNull(nameof(source))] + internal static V2alpha1ConnectionConf? FromApi(GetConnectionResponseContent? source) + { + if (source is null) + return null; + + var conf = new V2alpha1ConnectionConf() + { + Name = source.Name, + DisplayName = source.DisplayName, + Strategy = JsonSerializer.Deserialize(JsonSerializer.Serialize(source.Strategy)), + Realms = source.Realms?.ToArray(), + IsDomainConnection = source.IsDomainConnection, + ShowAsButton = source.ShowAsButton, + Metadata = source.Metadata is { } md ? new System.Collections.Hashtable(md) : null, + Options = new V2alpha1ConnectionOptions() + }; + + switch (source.Strategy) + { + case ConnectionResponseContentAuth0Strategy.Values.Auth0: + conf.Options.Auth0 = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentAdStrategy.Values.Ad: + conf.Options.Ad = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentAdfsStrategy.Values.Adfs: + conf.Options.Adfs = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentAmazonStrategy.Values.Amazon: + break; + case ConnectionResponseContentAppleStrategy.Values.Apple: + break; + case ConnectionResponseContentAuth0OidcStrategy.Values.Auth0Oidc: + conf.Options.Auth0Oidc = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentBaiduStrategy.Values.Baidu: + break; + case ConnectionResponseContentBitbucketStrategy.Values.Bitbucket: + conf.Options.Bitbucket = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentBitlyStrategy.Values.Bitly: + break; + case ConnectionResponseContentBoxStrategy.Values.Box: + conf.Options.Box = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentDaccountStrategy.Values.Daccount: + break; + case ConnectionResponseContentDropboxStrategy.Values.Dropbox: + conf.Options.Dropbox = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentDwollaStrategy.Values.Dwolla: + break; + case ConnectionResponseContentEmailStrategy.Values.Email: + conf.Options.Email = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentEvernoteStrategy.Values.Evernote: + conf.Options.Evernote = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentEvernoteSandboxStrategy.Values.EvernoteSandbox: + conf.Options.EvernoteSandbox = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentExactStrategy.Values.Exact: + conf.Options.Exact = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentFacebookStrategy.Values.Facebook: + conf.Options.Facebook = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentFitbitStrategy.Values.Fitbit: + break; + case ConnectionResponseContentGitHubStrategy.Values.Github: + conf.Options.GitHub = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentGoogleAppsStrategy.Values.GoogleApps: + conf.Options.GoogleApps = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentGoogleOAuth2Strategy.Values.GoogleOauth2: + conf.Options.GoogleOAuth2 = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentInstagramStrategy.Values.Instagram: + break; + case ConnectionResponseContentLineStrategy.Values.Line: + break; + case ConnectionResponseContentLinkedinStrategy.Values.Linkedin: + conf.Options.Linkedin = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentOAuth1Strategy.Values.Oauth1: + conf.Options.OAuth1 = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentOAuth2Strategy.Values.Oauth2: + conf.Options.OAuth2 = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentOffice365Strategy.Values.Office365: + conf.Options.Office365 = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentOidcStrategy.Values.Oidc: + conf.Options.Oidc = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentOktaStrategy.Values.Okta: + conf.Options.Okta = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentPaypalStrategy.Values.Paypal: + conf.Options.Paypal = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentPaypalSandboxStrategy.Values.PaypalSandbox: + conf.Options.PaypalSandbox = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentPingFederateStrategy.Values.Pingfederate: + conf.Options.PingFederate = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentPlanningCenterStrategy.Values.Planningcenter: + break; + case ConnectionResponseContentSalesforceStrategy.Values.Salesforce: + conf.Options.Salesforce = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentSalesforceCommunityStrategy.Values.SalesforceCommunity: + conf.Options.SalesforceCommunity = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentSalesforceSandboxStrategy.Values.SalesforceSandbox: + conf.Options.SalesforceSandbox = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentSamlStrategy.Values.Samlp: + conf.Options.Saml = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentSharepointStrategy.Values.Sharepoint: + break; + case ConnectionResponseContentShopifyStrategy.Values.Shopify: + break; + case ConnectionResponseContentShopStrategy.Values.Shop: + break; + case ConnectionResponseContentSmsStrategy.Values.Sms: + conf.Options.Sms = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentSoundcloudStrategy.Values.Soundcloud: + break; + case ConnectionResponseContentThirtySevenSignalsStrategy.Values.Thirtysevensignals: + break; + case ConnectionResponseContentTwitterStrategy.Values.Twitter: + conf.Options.Twitter = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentUntappdStrategy.Values.Untappd: + break; + case ConnectionResponseContentVkontakteStrategy.Values.Vkontakte: + break; + case ConnectionResponseContentAzureAdStrategy.Values.Waad: + conf.Options.AzureAd = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentWeiboStrategy.Values.Weibo: + break; + case ConnectionResponseContentWindowsLiveStrategy.Values.Windowslive: + conf.Options.WindowsLive = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentWordpressStrategy.Values.Wordpress: + break; + case ConnectionResponseContentYahooStrategy.Values.Yahoo: + conf.Options.Yahoo = FromApi(JsonConvertTo(source)?.Options); + break; + case ConnectionResponseContentYandexStrategy.Values.Yandex: + break; + default: + break; + } + + return conf; + } + + internal static V2alpha1ConnectionOptionsAuth0? FromApi(ConnectionOptionsAuth0? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsAuth0 + { + Attributes = source.Attributes is { } attributes ? FromApi(attributes) : null, + AuthenticationMethods = source.AuthenticationMethods.IsDefined && source.AuthenticationMethods.Value is { } authenticationMethods ? FromApi(authenticationMethods) : null, + BruteForceProtection = source.BruteForceProtection, + Configuration = source.Configuration?.ToDictionary(kv => kv.Key, kv => kv.Value), + DisableSignup = source.DisableSignup, + DisableSelfServiceChangePassword = source.DisableSelfServiceChangePassword, + EnableScriptContext = source.EnableScriptContext, + EnabledDatabaseCustomization = source.EnabledDatabaseCustomization, + ImportMode = source.ImportMode, + Mfa = source.Mfa is { } mfa ? FromApi(mfa) : null, + PasskeyOptions = source.PasskeyOptions.IsDefined && source.PasskeyOptions.Value is { } passkeyOptions ? FromApi(passkeyOptions) : null, + PasswordOptions = source.PasswordOptions is { } passwordOptions ? FromApi(passwordOptions) : null, + Precedence = source.Precedence?.Select(static i => i.Value switch + { + ConnectionIdentifierPrecedenceEnum.Values.Email => V2alpha1ConnectionIdentifierPrecedenceEnum.Email, + ConnectionIdentifierPrecedenceEnum.Values.PhoneNumber => V2alpha1ConnectionIdentifierPrecedenceEnum.PhoneNumber, + ConnectionIdentifierPrecedenceEnum.Values.Username => V2alpha1ConnectionIdentifierPrecedenceEnum.Username, + _ => throw new ArgumentOutOfRangeException(nameof(source), i, null), + }).ToArray(), + RealmFallback = source.RealmFallback, + RequiresUsername = source.RequiresUsername, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + PasswordPolicy = source.PasswordPolicy.IsDefined ? FromApi(source.PasswordPolicy.Value) : null, + PasswordHistory = source.PasswordHistory.IsDefined && source.PasswordHistory.Value is { } ph ? FromApi(ph) : null, + PasswordNoPersonalInfo = source.PasswordNoPersonalInfo.IsDefined && source.PasswordNoPersonalInfo.Value is { } pnpi ? FromApi(pnpi) : null, + PasswordDictionary = source.PasswordDictionary.IsDefined && source.PasswordDictionary.Value is { } pd ? FromApi(pd) : null, + PasswordComplexityOptions = source.PasswordComplexityOptions.IsDefined && source.PasswordComplexityOptions.Value is { } pco ? FromApi(pco) : null, + Validation = source.Validation.IsDefined && source.Validation.Value is { } v ? FromApi(v) : null, + CustomScripts = source.CustomScripts is { } cs ? FromApi(cs) : null, + }; + } + + internal static V2alpha1ConnectionOptionsAd? FromApi(ConnectionOptionsAd? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsAd + { + AgentIp = source.AgentIp, + AgentMode = source.AgentMode, + AgentVersion = source.AgentVersion, + BruteForceProtection = source.BruteForceProtection, + CertAuth = source.CertAuth, + Certs = source.Certs?.ToArray(), + DisableCache = source.DisableCache, + DisableSelfServiceChangePassword = source.DisableSelfServiceChangePassword, + DomainAliases = source.DomainAliases?.ToArray(), + IconUrl = source.IconUrl, + Ips = source.Ips?.ToArray(), + SignInEndpoint = source.SignInEndpoint, + TenantDomain = source.TenantDomain, + Thumbprints = source.Thumbprints?.ToArray(), + UpstreamParams = FromApi(source.UpstreamParams), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + Kerberos = source.Kerberos, + }; + } + + internal static V2alpha1ConnectionOptionsAdfs? FromApi(ConnectionOptionsAdfs? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsAdfs + { + AdfsServer = source.AdfsServer, + DomainAliases = source.DomainAliases?.ToArray(), + EntityId = source.EntityId, + FedMetadataXml = source.FedMetadataXml, + IconUrl = source.IconUrl, + PrevThumbprints = source.PrevThumbprints?.ToArray(), + ShouldTrustEmailVerifiedConnection = source.ShouldTrustEmailVerifiedConnection switch + { + { Value: ConnectionShouldTrustEmailVerifiedConnectionEnum.Values.NeverSetEmailsAsVerified } => V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum.NeverSetEmailsAsVerified, + { Value: ConnectionShouldTrustEmailVerifiedConnectionEnum.Values.AlwaysSetEmailsAsVerified } => V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum.AlwaysSetEmailsAsVerified, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source.ShouldTrustEmailVerifiedConnection, null), + }, + SignInEndpoint = source.SignInEndpoint, + TenantDomain = source.TenantDomain, + Thumbprints = source.Thumbprints?.ToArray(), + UserIdAttribute = source.UserIdAttribute, + UpstreamParams = FromApi(source.UpstreamParams), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + }; + } + + internal static V2alpha1ConnectionOptionsAuth0Oidc? FromApi(ConnectionOptionsAuth0Oidc? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsAuth0Oidc + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + }; + } + + internal static V2alpha1ConnectionOptionsAzureAd? FromApi(ConnectionOptionsAzureAd? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsAzureAd + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + ApiEnableUsers = source.ApiEnableUsers, + AppDomain = source.AppDomain, + AppId = source.AppId, + BasicProfile = source.BasicProfile, + DomainAliases = source.DomainAliases?.ToArray(), + ExtAccessToken = source.ExtAccessToken, + ExtAccountEnabled = source.ExtAccountEnabled, + ExtAdmin = source.ExtAdmin, + ExtAgreedTerms = source.ExtAgreedTerms, + ExtAssignedLicenses = source.ExtAssignedLicenses, + ExtAssignedPlans = source.ExtAssignedPlans, + ExtAzureId = source.ExtAzureId, + ExtCity = source.ExtCity, + ExtCountry = source.ExtCountry, + ExtDepartment = source.ExtDepartment, + ExtDirSyncEnabled = source.ExtDirSyncEnabled, + ExtEmail = source.ExtEmail, + ExtExpiresIn = source.ExtExpiresIn, + ExtFamilyName = source.ExtFamilyName, + ExtFax = source.ExtFax, + ExtGivenName = source.ExtGivenName, + ExtGroupIds = source.ExtGroupIds, + ExtGroups = source.ExtGroups, + ExtIsSuspended = source.ExtIsSuspended, + ExtJobTitle = source.ExtJobTitle, + ExtLastSync = source.ExtLastSync, + ExtMobile = source.ExtMobile, + ExtName = source.ExtName, + ExtNestedGroups = source.ExtNestedGroups, + ExtNickname = source.ExtNickname, + ExtOid = source.ExtOid, + ExtPhone = source.ExtPhone, + ExtPhysicalDeliveryOfficeName = source.ExtPhysicalDeliveryOfficeName, + ExtPostalCode = source.ExtPostalCode, + ExtPreferredLanguage = source.ExtPreferredLanguage, + ExtProfile = source.ExtProfile, + ExtProvisionedPlans = source.ExtProvisionedPlans, + ExtProvisioningErrors = source.ExtProvisioningErrors, + ExtProxyAddresses = source.ExtProxyAddresses, + ExtPuid = source.ExtPuid, + ExtRefreshToken = source.ExtRefreshToken, + ExtRoles = source.ExtRoles, + ExtState = source.ExtState, + ExtStreet = source.ExtStreet, + ExtTelephoneNumber = source.ExtTelephoneNumber, + ExtTenantid = source.ExtTenantid, + ExtUpn = source.ExtUpn, + ExtUsageLocation = source.ExtUsageLocation, + ExtUserId = source.ExtUserId, + Granted = source.Granted, + IconUrl = source.IconUrl, + IdentityApi = source.IdentityApi switch + { + { Value: ConnectionIdentityApiEnumAzureAd.Values.MicrosoftIdentityPlatformV20 } => V2alpha1ConnectionIdentityApiEnumAzureAd.MicrosoftIdentityPlatformV20, + { Value: ConnectionIdentityApiEnumAzureAd.Values.AzureActiveDirectoryV10 } => V2alpha1ConnectionIdentityApiEnumAzureAd.AzureActiveDirectoryV10, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source.IdentityApi, null), + }, + MaxGroupsToRetrieve = source.MaxGroupsToRetrieve, + Scope = source.Scope?.ToArray(), + ShouldTrustEmailVerifiedConnection = source.ShouldTrustEmailVerifiedConnection switch + { + { Value: ConnectionShouldTrustEmailVerifiedConnectionEnum.Values.NeverSetEmailsAsVerified } => V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum.NeverSetEmailsAsVerified, + { Value: ConnectionShouldTrustEmailVerifiedConnectionEnum.Values.AlwaysSetEmailsAsVerified } => V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum.AlwaysSetEmailsAsVerified, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source.ShouldTrustEmailVerifiedConnection, null), + }, + TenantDomain = source.TenantDomain, + TenantId = source.TenantId, + Thumbprints = source.Thumbprints?.ToArray(), + UseCommonEndpoint = source.UseCommonEndpoint, + UseWsfed = source.UseWsfed, + FederatedConnectionsAccessTokens = source.FederatedConnectionsAccessTokens.IsDefined && source.FederatedConnectionsAccessTokens.Value is { } fcat ? FromApi(fcat) : null, + UseridAttribute = source.UseridAttribute switch + { + { Value: ConnectionUseridAttributeEnumAzureAd.Values.Oid } => V2alpha1ConnectionUseridAttributeEnumAzureAd.Oid, + { Value: ConnectionUseridAttributeEnumAzureAd.Values.Sub } => V2alpha1ConnectionUseridAttributeEnumAzureAd.Sub, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source.UseridAttribute, null), + }, + WaadProtocol = source.WaadProtocol switch + { + { Value: ConnectionWaadProtocolEnumAzureAd.Values.WsFederation } => V2alpha1ConnectionWaadProtocolEnumAzureAd.WsFederation, + { Value: ConnectionWaadProtocolEnumAzureAd.Values.OpenidConnect } => V2alpha1ConnectionWaadProtocolEnumAzureAd.OpenidConnect, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source.WaadProtocol, null), + }, + UpstreamParams = FromApi(source.UpstreamParams), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + }; + } + + internal static V2alpha1ConnectionOptionsBitbucket? FromApi(ConnectionOptionsBitbucket? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsBitbucket + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + Scope = source.Scope is not null ? source.Scope.ToArray() : null, + FreeformScopes = source.FreeformScopes?.ToArray(), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + Profile = source.Profile, + }; + } + + internal static V2alpha1ConnectionOptionsBox? FromApi(ConnectionOptionsBox? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsBox + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsDropbox? FromApi(ConnectionOptionsDropbox? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsDropbox + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsEmail? FromApi(ConnectionOptionsEmail? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsEmail + { + Name = source.Name, + Email = source.Email is { } e ? new V2alpha1ConnectionEmailEmail + { + From = e.From, + Subject = e.Subject, + Body = e.Body, + Syntax = FromApi(e.Syntax), + } : null, + Totp = source.Totp is { } t ? new V2alpha1ConnectionTotpEmail + { + Length = t.Length, + TimeStep = t.TimeStep, + } : null, + BruteForceProtection = source.BruteForceProtection, + DisableSignup = source.DisableSignup, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + }; + } + + internal static V2alpha1ConnectionOptionsEvernote? FromApi(ConnectionOptionsEvernote? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsEvernote + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsExact? FromApi(ConnectionOptionsExact? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsExact + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsFacebook? FromApi(ConnectionOptionsFacebook? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsFacebook + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + Scope = source.Scope, + FreeformScopes = source.FreeformScopes?.ToArray(), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + Email = source.Email, + AdsManagement = source.AdsManagement, + AdsRead = source.AdsRead, + BusinessManagement = source.BusinessManagement, + GroupsAccessMemberInfo = source.GroupsAccessMemberInfo, + LeadsRetrieval = source.LeadsRetrieval, + ManagePages = source.ManagePages, + PagesMessaging = source.PagesMessaging, + PagesMessagingPhoneNumber = source.PagesMessagingPhoneNumber, + PagesMessagingSubscriptions = source.PagesMessagingSubscriptions, + PagesShowList = source.PagesShowList, + PublishToGroups = source.PublishToGroups, + ReadAudienceNetworkInsights = source.ReadAudienceNetworkInsights, + ReadInsights = source.ReadInsights, + ReadPageMailboxes = source.ReadPageMailboxes, + PublicProfile = source.PublicProfile, + UserBirthday = source.UserBirthday, + UserLikes = source.UserLikes, + UserGender = source.UserGender, + UserAgeRange = source.UserAgeRange, + UserLocation = source.UserLocation, + UserHometown = source.UserHometown, + UserFriends = source.UserFriends, + UserLink = source.UserLink, + UserPhotos = source.UserPhotos, + UserVideos = source.UserVideos, + UserPosts = source.UserPosts, + UserStatus = source.UserStatus, + UserTaggedPlaces = source.UserTaggedPlaces, + UserEvents = source.UserEvents, + UserGroups = source.UserGroups, + UserManagedGroups = source.UserManagedGroups, + ManageNotifications = source.ManageNotifications, + PublishActions = source.PublishActions, + PublishPages = source.PublishPages, + PublishVideo = source.PublishVideo, + ReadMailbox = source.ReadMailbox, + ReadStream = source.ReadStream, + AllowContextProfileField = source.AllowContextProfileField, + PagesManageCta = source.PagesManageCta, + PagesManageInstantArticles = source.PagesManageInstantArticles, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsGitHub? FromApi(ConnectionOptionsGitHub? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsGitHub + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + Scope = source.Scope is not null ? source.Scope.ToArray() : null, + FreeformScopes = source.FreeformScopes?.ToArray(), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + AdminOrg = source.AdminOrg, + AdminPublicKey = source.AdminPublicKey, + AdminRepoHook = source.AdminRepoHook, + DeleteRepo = source.DeleteRepo, + Email = source.Email, + Follow = source.Follow, + Gist = source.Gist, + Notifications = source.Notifications, + PublicRepo = source.PublicRepo, + ReadOrg = source.ReadOrg, + ReadPublicKey = source.ReadPublicKey, + ReadRepoHook = source.ReadRepoHook, + ReadUser = source.ReadUser, + Repo = source.Repo, + RepoDeployment = source.RepoDeployment, + RepoStatus = source.RepoStatus, + WriteOrg = source.WriteOrg, + WritePublicKey = source.WritePublicKey, + WriteRepoHook = source.WriteRepoHook, + Profile = source.Profile, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsGoogleApps? FromApi(ConnectionOptionsGoogleApps? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsGoogleApps + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + Scope = source.Scope is not null ? source.Scope.ToArray() : null, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + Domain = source.Domain, + DomainAliases = source.DomainAliases?.ToArray(), + TenantDomain = source.TenantDomain, + IconUrl = source.IconUrl, + Email = source.Email, + Profile = source.Profile, + ApiEnableUsers = source.ApiEnableUsers, + MapUserIdToId = source.MapUserIdToId, + AdminAccessToken = source.AdminAccessToken, + AdminAccessTokenExpiresin = source.AdminAccessTokenExpiresin, + AdminRefreshToken = source.AdminRefreshToken, + AllowSettingLoginScopes = source.AllowSettingLoginScopes, + ApiEnableGroups = source.ApiEnableGroups, + ExtAgreedTerms = source.ExtAgreedTerms, + ExtGroups = source.ExtGroups, + ExtGroupsExtended = source.ExtGroupsExtended, + ExtIsAdmin = source.ExtIsAdmin, + ExtIsSuspended = source.ExtIsSuspended, + FederatedConnectionsAccessTokens = source.FederatedConnectionsAccessTokens.IsDefined && source.FederatedConnectionsAccessTokens.Value is { } fcat + ? new V2alpha1ConnectionFederatedConnectionsAccessTokens { Active = fcat.Active } + : null, + HandleLoginFromSocial = source.HandleLoginFromSocial, + }; + } + + internal static V2alpha1ConnectionOptionsGoogleOAuth2? FromApi(ConnectionOptionsGoogleOAuth2? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsGoogleOAuth2 + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + Scope = source.Scope?.ToArray(), + FreeformScopes = source.FreeformScopes?.ToArray(), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + IconUrl = source.IconUrl, + AllowedAudiences = source.AllowedAudiences?.ToArray(), + Email = source.Email, + Profile = source.Profile, + OfflineAccess = source.OfflineAccess, + AdsenseManagement = source.AdsenseManagement, + Analytics = source.Analytics, + Blogger = source.Blogger, + Calendar = source.Calendar, + CalendarAddonsExecute = source.CalendarAddonsExecute, + CalendarEvents = source.CalendarEvents, + CalendarEventsReadonly = source.CalendarEventsReadonly, + CalendarSettingsReadonly = source.CalendarSettingsReadonly, + ChromeWebStore = source.ChromeWebStore, + Contacts = source.Contacts, + ContactsNew = source.ContactsNew, + ContactsOtherReadonly = source.ContactsOtherReadonly, + ContactsReadonly = source.ContactsReadonly, + ContentApiForShopping = source.ContentApiForShopping, + Coordinate = source.Coordinate, + CoordinateReadonly = source.CoordinateReadonly, + DirectoryReadonly = source.DirectoryReadonly, + DocumentList = source.DocumentList, + Drive = source.Drive, + DriveActivity = source.DriveActivity, + DriveActivityReadonly = source.DriveActivityReadonly, + DriveAppdata = source.DriveAppdata, + DriveAppsReadonly = source.DriveAppsReadonly, + DriveFile = source.DriveFile, + DriveMetadata = source.DriveMetadata, + DriveMetadataReadonly = source.DriveMetadataReadonly, + DrivePhotosReadonly = source.DrivePhotosReadonly, + DriveReadonly = source.DriveReadonly, + DriveScripts = source.DriveScripts, + Gmail = source.Gmail, + GmailCompose = source.GmailCompose, + GmailInsert = source.GmailInsert, + GmailLabels = source.GmailLabels, + GmailMetadata = source.GmailMetadata, + GmailModify = source.GmailModify, + GmailNew = source.GmailNew, + GmailReadonly = source.GmailReadonly, + GmailSend = source.GmailSend, + GmailSettingsBasic = source.GmailSettingsBasic, + GmailSettingsSharing = source.GmailSettingsSharing, + GoogleAffiliateNetwork = source.GoogleAffiliateNetwork, + GoogleBooks = source.GoogleBooks, + GoogleCloudStorage = source.GoogleCloudStorage, + GoogleDrive = source.GoogleDrive, + GoogleDriveFiles = source.GoogleDriveFiles, + GooglePlus = source.GooglePlus, + LatitudeBest = source.LatitudeBest, + LatitudeCity = source.LatitudeCity, + Moderator = source.Moderator, + Orkut = source.Orkut, + PicasaWeb = source.PicasaWeb, + Sites = source.Sites, + Tasks = source.Tasks, + TasksReadonly = source.TasksReadonly, + UrlShortener = source.UrlShortener, + WebmasterTools = source.WebmasterTools, + Youtube = source.Youtube, + YoutubeChannelmembershipsCreator = source.YoutubeChannelmembershipsCreator, + YoutubeNew = source.YoutubeNew, + YoutubeReadonly = source.YoutubeReadonly, + YoutubeUpload = source.YoutubeUpload, + Youtubepartner = source.Youtubepartner, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsLinkedin? FromApi(ConnectionOptionsLinkedin? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsLinkedin + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + Scope = source.Scope?.ToArray(), + FreeformScopes = source.FreeformScopes?.ToArray(), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + BasicProfile = source.BasicProfile, + Email = source.Email, + Openid = source.Openid, + FullProfile = source.FullProfile, + StrategyVersion = source.StrategyVersion, + Network = source.Network, + Profile = source.Profile, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsOAuth1? FromApi(ConnectionOptionsOAuth1? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsOAuth1 + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + AccessTokenUrl = source.AccessTokenUrl, + RequestTokenUrl = source.RequestTokenUrl, + SignatureMethod = FromApi(source.SignatureMethod), + UserAuthorizationUrl = source.UserAuthorizationUrl, + Scripts = source.Scripts is { } sc ? new V2alpha1ConnectionScriptsOAuth1 { FetchUserProfile = sc.FetchUserProfile } : null, + UpstreamParams = FromApi(source.UpstreamParams), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + }; + } + + internal static V2alpha1ConnectionOptionsOAuth2? FromApi(ConnectionOptionsOAuth2? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsOAuth2 + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + AuthorizationUrl = source.AuthorizationUrl, + TokenUrl = source.TokenUrl, + LogoutUrl = source.LogoutUrl, + Scope = source.Scope is not null ? source.Scope.ToString()!.Split(' ', StringSplitOptions.RemoveEmptyEntries) : null, + IconUrl = source.IconUrl, + PkceEnabled = source.PkceEnabled, + UseOauthSpecScope = source.UseOauthSpecScope, + Scripts = source.Scripts is { } sc ? new V2alpha1ConnectionScriptsOAuth2 { FetchUserProfile = sc.FetchUserProfile } : null, + AuthParams = source.AuthParams?.ToDictionary(kv => kv.Key, kv => kv.Value), + AuthParamsMap = source.AuthParamsMap?.ToDictionary(kv => kv.Key, kv => kv.Value), + FieldsMap = source.FieldsMap?.ToDictionary(kv => kv.Key, kv => kv.Value), + CustomHeaders = source.CustomHeaders?.ToDictionary(kv => kv.Key, kv => kv.Value), + UpstreamParams = FromApi(source.UpstreamParams), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + }; + } + + internal static V2alpha1ConnectionOptionsOffice365? FromApi(ConnectionOptionsOffice365? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsOffice365 + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + }; + } + + internal static V2alpha1ConnectionOptionsOidc? FromApi(ConnectionOptionsOidc? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsOidc + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + DiscoveryUrl = source.DiscoveryUrl, + AuthorizationEndpoint = source.AuthorizationEndpoint, + TokenEndpoint = source.TokenEndpoint, + UserinfoEndpoint = source.UserinfoEndpoint, + JwksUri = source.JwksUri, + Issuer = source.Issuer, + Scope = source.Scope, + IconUrl = source.IconUrl, + DomainAliases = source.DomainAliases?.ToArray(), + TenantDomain = source.TenantDomain, + TokenEndpointAuthMethod = source.TokenEndpointAuthMethod.IsDefined ? FromApi(source.TokenEndpointAuthMethod.Value) : null, + TokenEndpointAuthSigningAlg = source.TokenEndpointAuthSigningAlg.IsDefined ? FromApi(source.TokenEndpointAuthSigningAlg.Value) : null, + TokenEndpointJwtcaAudFormat = FromApi(source.TokenEndpointJwtcaAudFormat), + DpopSigningAlg = FromApi(source.DpopSigningAlg), + IdTokenSignedResponseAlgs = source.IdTokenSignedResponseAlgs.IsDefined && source.IdTokenSignedResponseAlgs.Value is { } algs ? algs.Select(FromApi).ToArray() : null, + SendBackChannelNonce = source.SendBackChannelNonce, + Type = FromApi(source.Type), + OidcMetadata = source.OidcMetadata is { } oidcMetadata ? FromApi(oidcMetadata) : null, + AttributeMap = source.AttributeMap is { } am ? FromApi(am) : null, + ConnectionSettings = source.ConnectionSettings is { } cs ? FromApi(cs) : null, + FederatedConnectionsAccessTokens = source.FederatedConnectionsAccessTokens.IsDefined && source.FederatedConnectionsAccessTokens.Value is { } fcat ? FromApi(fcat) : null, + UpstreamParams = FromApi(source.UpstreamParams), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + }; + } + + internal static V2alpha1ConnectionOptionsOkta? FromApi(ConnectionOptionsOkta? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsOkta + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + AuthorizationEndpoint = source.AuthorizationEndpoint, + TokenEndpoint = source.TokenEndpoint, + UserinfoEndpoint = source.UserinfoEndpoint, + JwksUri = source.JwksUri, + Issuer = source.Issuer, + Scope = source.Scope, + IconUrl = source.IconUrl, + DomainAliases = source.DomainAliases?.ToArray(), + TenantDomain = source.TenantDomain, + TokenEndpointAuthMethod = source.TokenEndpointAuthMethod.IsDefined ? FromApi(source.TokenEndpointAuthMethod.Value) : null, + TokenEndpointAuthSigningAlg = source.TokenEndpointAuthSigningAlg.IsDefined ? FromApi(source.TokenEndpointAuthSigningAlg.Value) : null, + TokenEndpointJwtcaAudFormat = FromApi(source.TokenEndpointJwtcaAudFormat), + DpopSigningAlg = FromApi(source.DpopSigningAlg), + IdTokenSignedResponseAlgs = source.IdTokenSignedResponseAlgs.IsDefined && source.IdTokenSignedResponseAlgs.Value is { } algs ? algs.Select(FromApi).ToArray() : null, + SendBackChannelNonce = source.SendBackChannelNonce, + Type = FromApi(source.Type), + OidcMetadata = source.OidcMetadata is { } oidcMetadata ? FromApi(oidcMetadata) : null, + AttributeMap = source.AttributeMap is { } am ? FromApi(am) : null, + ConnectionSettings = source.ConnectionSettings is { } cs ? FromApi(cs) : null, + FederatedConnectionsAccessTokens = source.FederatedConnectionsAccessTokens.IsDefined && source.FederatedConnectionsAccessTokens.Value is { } fcat ? FromApi(fcat) : null, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + Domain = source.Domain, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsPaypal? FromApi(ConnectionOptionsPaypal? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsPaypal + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + Scope = source.Scope?.ToArray(), + FreeformScopes = source.FreeformScopes?.ToArray(), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + Address = source.Address, + Email = source.Email, + Phone = source.Phone, + Profile = source.Profile, + }; + } + + internal static V2alpha1ConnectionOptionsPingFederate? FromApi(ConnectionOptionsPingFederate? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsPingFederate + { + PingFederateBaseUrl = source.PingFederateBaseUrl, + SignInEndpoint = source.SignInEndpoint, + EntityId = source.EntityId, + Cert = source.Cert, + SigningCert = source.SigningCert, + Thumbprints = source.Thumbprints?.ToArray(), + SignatureAlgorithm = FromApi(source.SignatureAlgorithm), + DigestAlgorithm = FromApi(source.DigestAlgorithm), + SignSamlRequest = source.SignSamlRequest, + ProtocolBinding = FromApi(source.ProtocolBinding), + Idpinitiated = source.Idpinitiated is { } idp ? FromApi(idp) : null, + DecryptionKey = FromApi(source.DecryptionKey), + AssertionDecryptionSettings = source.AssertionDecryptionSettings is { } ads ? FromApi(ads) : null, + IconUrl = source.IconUrl, + DomainAliases = source.DomainAliases?.ToArray(), + TenantDomain = source.TenantDomain, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsSalesforce? FromApi(ConnectionOptionsSalesforce? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsSalesforce + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + Scope = source.Scope?.ToArray(), + FreeformScopes = source.FreeformScopes?.ToArray(), + Profile = source.Profile, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsSalesforceCommunity? FromApi(ConnectionOptionsSalesforceCommunity? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsSalesforceCommunity + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + CommunityBaseUrl = source.CommunityBaseUrl, + Scope = source.Scope?.ToArray(), + FreeformScopes = source.FreeformScopes?.ToArray(), + Profile = source.Profile, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsSaml? FromApi(ConnectionOptionsSaml? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsSaml + { + SignInEndpoint = source.SignInEndpoint, + SignOutEndpoint = source.SignOutEndpoint, + DisableSignout = source.DisableSignout, + DestinationUrl = source.DestinationUrl, + RecipientUrl = source.RecipientUrl, + Cert = source.Cert, + Thumbprints = source.Thumbprints?.ToArray(), + MetadataUrl = source.MetadataUrl, + MetadataXml = source.MetadataXml, + EntityId = source.EntityId, + SignatureAlgorithm = FromApi(source.SignatureAlgorithm), + DigestAlgorithm = FromApi(source.DigestAlgorithm), + SignSamlRequest = source.SignSamlRequest, + ProtocolBinding = FromApi(source.ProtocolBinding), + RequestTemplate = source.RequestTemplate, + Debug = source.Debug, + Deflate = source.Deflate, + Idpinitiated = source.Idpinitiated is { } idp ? FromApi(idp) : null, + SigningCert = source.SigningCert, + SigningKey = source.SigningKey is { } signingKey ? new V2alpha1ConnectionSigningKeySaml { Key = signingKey.Key, Cert = signingKey.Cert } : null, + DecryptionKey = FromApi(source.DecryptionKey), + AssertionDecryptionSettings = source.AssertionDecryptionSettings is { } ads ? FromApi(ads) : null, + FieldsMap = null, + UserIdAttribute = source.UserIdAttribute, + IconUrl = source.IconUrl, + DomainAliases = source.DomainAliases?.ToArray(), + TenantDomain = source.TenantDomain, + GlobalTokenRevocationJwtIss = source.GlobalTokenRevocationJwtIss, + GlobalTokenRevocationJwtSub = source.GlobalTokenRevocationJwtSub, + UpstreamParams = FromApi(source.UpstreamParams), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + }; + } + + internal static V2alpha1ConnectionDecryptionKeySaml? FromApi(ConnectionDecryptionKeySaml? source) + { + if (source is null) + return null; + + if (source.IsString()) + { + return new V2alpha1ConnectionDecryptionKeySaml + { + PrivateKey = source.AsString(), + }; + } + + if (source.IsConnectionDecryptionKeySamlCert()) + { + var cert = source.AsConnectionDecryptionKeySamlCert(); + return new V2alpha1ConnectionDecryptionKeySaml + { + KeyPair = new V2alpha1ConnectionDecryptionKeySamlCert + { + Cert = cert.Cert, + Key = cert.Key, + }, + }; + } + + return new V2alpha1ConnectionDecryptionKeySaml(); + } + + internal static ConnectionDecryptionKeySaml? ToApi(V2alpha1ConnectionDecryptionKeySaml? source) + { + if (source is null) + return null; + + if (source.PrivateKey is { } privateKey) + { + return ConnectionDecryptionKeySaml.FromString(privateKey); + } + + if (source.KeyPair is { } keyPair) + { + return ConnectionDecryptionKeySaml.FromConnectionDecryptionKeySamlCert( + new ConnectionDecryptionKeySamlCert + { + Cert = keyPair.Cert, + Key = keyPair.Key, + }); + } + + return null; + } + + internal static V2alpha1ConnectionOptionsSms? FromApi(ConnectionOptionsSms? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsSms + { + Name = source.Name, + From = source.From, + Template = source.Template, + Syntax = FromApi(source.Syntax), + Provider = FromApi(source.Provider), + TwilioSid = source.TwilioSid, + TwilioToken = source.TwilioToken, + MessagingServiceSid = source.MessagingServiceSid, + GatewayUrl = source.GatewayUrl, + ForwardReqInfo = source.ForwardReqInfo, + DisableSignup = source.DisableSignup, + BruteForceProtection = source.BruteForceProtection, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + Totp = source.Totp is { } t ? new V2alpha1ConnectionTotpSms { Length = t.Length, TimeStep = t.TimeStep } : null, + GatewayAuthentication = source.GatewayAuthentication.IsDefined && source.GatewayAuthentication.Value is { } ga ? FromApi(ga) : null, + }; + } + + internal static V2alpha1ConnectionOptionsTwitter? FromApi(ConnectionOptionsTwitter? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsTwitter + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + Scope = source.Scope?.ToArray(), + FreeformScopes = source.FreeformScopes?.ToArray(), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + Protocol = FromApi(source.Protocol), + OfflineAccess = source.OfflineAccess, + Profile = source.Profile, + TweetRead = source.TweetRead, + UsersRead = source.UsersRead, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsWindowsLive? FromApi(ConnectionOptionsWindowsLive? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsWindowsLive + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + Scope = source.Scope?.ToArray(), + FreeformScopes = source.FreeformScopes?.ToArray(), + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + Basic = source.Basic, + OfflineAccess = source.OfflineAccess, + Signin = source.Signin, + Birthday = source.Birthday, + Calendars = source.Calendars, + CalendarsUpdate = source.CalendarsUpdate, + ContactsBirthday = source.ContactsBirthday, + ContactsCreate = source.ContactsCreate, + ContactsCalendars = source.ContactsCalendars, + ContactsPhotos = source.ContactsPhotos, + ContactsSkydrive = source.ContactsSkydrive, + Emails = source.Emails, + EventsCreate = source.EventsCreate, + Messenger = source.Messenger, + PhoneNumbers = source.PhoneNumbers, + Photos = source.Photos, + PostalAddresses = source.PostalAddresses, + Share = source.Share, + Skydrive = source.Skydrive, + SkydriveUpdate = source.SkydriveUpdate, + WorkProfile = source.WorkProfile, + Applications = source.Applications, + ApplicationsCreate = source.ApplicationsCreate, + StrategyVersion = source.StrategyVersion, + DirectoryAccessasuserAll = source.DirectoryAccessasuserAll, + DirectoryReadAll = source.DirectoryReadAll, + DirectoryReadwriteAll = source.DirectoryReadwriteAll, + GraphCalendars = source.GraphCalendars, + GraphCalendarsUpdate = source.GraphCalendarsUpdate, + GraphContacts = source.GraphContacts, + GraphContactsUpdate = source.GraphContactsUpdate, + GraphDevice = source.GraphDevice, + GraphDeviceCommand = source.GraphDeviceCommand, + GraphEmails = source.GraphEmails, + GraphEmailsUpdate = source.GraphEmailsUpdate, + GraphFiles = source.GraphFiles, + GraphFilesAll = source.GraphFilesAll, + GraphFilesAllUpdate = source.GraphFilesAllUpdate, + GraphFilesUpdate = source.GraphFilesUpdate, + GraphNotes = source.GraphNotes, + GraphNotesCreate = source.GraphNotesCreate, + GraphNotesUpdate = source.GraphNotesUpdate, + GraphTasks = source.GraphTasks, + GraphTasksUpdate = source.GraphTasksUpdate, + GraphUser = source.GraphUser, + GraphUserActivity = source.GraphUserActivity, + GraphUserUpdate = source.GraphUserUpdate, + GroupReadAll = source.GroupReadAll, + GroupReadwriteAll = source.GroupReadwriteAll, + MailReadwriteAll = source.MailReadwriteAll, + MailSend = source.MailSend, + RolemanagementReadAll = source.RolemanagementReadAll, + RolemanagementReadwriteDirectory = source.RolemanagementReadwriteDirectory, + SitesReadAll = source.SitesReadAll, + SitesReadwriteAll = source.SitesReadwriteAll, + TeamReadbasicAll = source.TeamReadbasicAll, + TeamReadwriteAll = source.TeamReadwriteAll, + UserReadAll = source.UserReadAll, + UserReadbasicAll = source.UserReadbasicAll, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionOptionsYahoo? FromApi(ConnectionOptionsYahoo? source) + { + if (source is null) + return null; + + return new V2alpha1ConnectionOptionsYahoo + { + ClientId = source.ClientId, + ClientSecret = source.ClientSecret, + NonPersistentAttrs = source.NonPersistentAttrs?.ToArray(), + SetUserRootAttributes = source.SetUserRootAttributes is { } sura ? FromApi(sura) : null, + UpstreamParams = FromApi(source.UpstreamParams), + }; + } + + internal static V2alpha1ConnectionSetUserRootAttributesEnum? FromApi(ConnectionSetUserRootAttributesEnum? source) + { + return source?.Value switch + { + ConnectionSetUserRootAttributesEnum.Values.OnEachLogin => V2alpha1ConnectionSetUserRootAttributesEnum.OnEachLogin, + ConnectionSetUserRootAttributesEnum.Values.OnFirstLogin => V2alpha1ConnectionSetUserRootAttributesEnum.OnFirstLogin, + ConnectionSetUserRootAttributesEnum.Values.NeverOnLogin => V2alpha1ConnectionSetUserRootAttributesEnum.NeverOnLogin, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static SignupStatusEnum? ToApi(V2alpha1ConnectionSignupStatusEnum? source) + { + return source switch + { + V2alpha1ConnectionSignupStatusEnum.Required => new SignupStatusEnum(SignupStatusEnum.Values.Required), + V2alpha1ConnectionSignupStatusEnum.Optional => new SignupStatusEnum(SignupStatusEnum.Values.Optional), + V2alpha1ConnectionSignupStatusEnum.Inactive => new SignupStatusEnum(SignupStatusEnum.Values.Inactive), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionShouldTrustEmailVerifiedConnectionEnum? ToApi(V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum? source) + { + return source switch + { + V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum.NeverSetEmailsAsVerified => new ConnectionShouldTrustEmailVerifiedConnectionEnum(ConnectionShouldTrustEmailVerifiedConnectionEnum.Values.NeverSetEmailsAsVerified), + V2alpha1ConnectionShouldTrustEmailVerifiedConnectionEnum.AlwaysSetEmailsAsVerified => new ConnectionShouldTrustEmailVerifiedConnectionEnum(ConnectionShouldTrustEmailVerifiedConnectionEnum.Values.AlwaysSetEmailsAsVerified), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionPasskeyChallengeUiEnum? ToApi(V2alpha1ConnectionPasskeyChallengeUiEnum? source) + { + return source switch + { + V2alpha1ConnectionPasskeyChallengeUiEnum.Both => new ConnectionPasskeyChallengeUiEnum(ConnectionPasskeyChallengeUiEnum.Values.Both), + V2alpha1ConnectionPasskeyChallengeUiEnum.Autofill => new ConnectionPasskeyChallengeUiEnum(ConnectionPasskeyChallengeUiEnum.Values.Autofill), + V2alpha1ConnectionPasskeyChallengeUiEnum.Button => new ConnectionPasskeyChallengeUiEnum(ConnectionPasskeyChallengeUiEnum.Values.Button), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionIdentityApiEnumAzureAd? ToApi(V2alpha1ConnectionIdentityApiEnumAzureAd? source) + { + return source switch + { + V2alpha1ConnectionIdentityApiEnumAzureAd.MicrosoftIdentityPlatformV20 => new ConnectionIdentityApiEnumAzureAd(ConnectionIdentityApiEnumAzureAd.Values.MicrosoftIdentityPlatformV20), + V2alpha1ConnectionIdentityApiEnumAzureAd.AzureActiveDirectoryV10 => new ConnectionIdentityApiEnumAzureAd(ConnectionIdentityApiEnumAzureAd.Values.AzureActiveDirectoryV10), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionUseridAttributeEnumAzureAd? ToApi(V2alpha1ConnectionUseridAttributeEnumAzureAd? source) + { + return source switch + { + V2alpha1ConnectionUseridAttributeEnumAzureAd.Oid => new ConnectionUseridAttributeEnumAzureAd(ConnectionUseridAttributeEnumAzureAd.Values.Oid), + V2alpha1ConnectionUseridAttributeEnumAzureAd.Sub => new ConnectionUseridAttributeEnumAzureAd(ConnectionUseridAttributeEnumAzureAd.Values.Sub), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionWaadProtocolEnumAzureAd? ToApi(V2alpha1ConnectionWaadProtocolEnumAzureAd? source) + { + return source switch + { + V2alpha1ConnectionWaadProtocolEnumAzureAd.WsFederation => new ConnectionWaadProtocolEnumAzureAd(ConnectionWaadProtocolEnumAzureAd.Values.WsFederation), + V2alpha1ConnectionWaadProtocolEnumAzureAd.OpenidConnect => new ConnectionWaadProtocolEnumAzureAd(ConnectionWaadProtocolEnumAzureAd.Values.OpenidConnect), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionSignatureMethodOAuth1? ToApi(V2alpha1ConnectionSignatureMethodOAuth1? source) + { + return source switch + { + V2alpha1ConnectionSignatureMethodOAuth1.RsaSha1 => new ConnectionSignatureMethodOAuth1(ConnectionSignatureMethodOAuth1.Values.RsaSha1), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionTokenEndpointAuthMethodEnum? ToApi(V2alpha1ConnectionTokenEndpointAuthMethodEnum? source) + { + return source switch + { + V2alpha1ConnectionTokenEndpointAuthMethodEnum.ClientSecretPost => new ConnectionTokenEndpointAuthMethodEnum(ConnectionTokenEndpointAuthMethodEnum.Values.ClientSecretPost), + V2alpha1ConnectionTokenEndpointAuthMethodEnum.PrivateKeyJwt => new ConnectionTokenEndpointAuthMethodEnum(ConnectionTokenEndpointAuthMethodEnum.Values.PrivateKeyJwt), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionTokenEndpointAuthSigningAlgEnum? ToApi(V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum? source) + { + return source switch + { + V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Es256 => new ConnectionTokenEndpointAuthSigningAlgEnum(ConnectionTokenEndpointAuthSigningAlgEnum.Values.Es256), + V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Es384 => new ConnectionTokenEndpointAuthSigningAlgEnum(ConnectionTokenEndpointAuthSigningAlgEnum.Values.Es384), + V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Ps256 => new ConnectionTokenEndpointAuthSigningAlgEnum(ConnectionTokenEndpointAuthSigningAlgEnum.Values.Ps256), + V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Ps384 => new ConnectionTokenEndpointAuthSigningAlgEnum(ConnectionTokenEndpointAuthSigningAlgEnum.Values.Ps384), + V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Rs256 => new ConnectionTokenEndpointAuthSigningAlgEnum(ConnectionTokenEndpointAuthSigningAlgEnum.Values.Rs256), + V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Rs384 => new ConnectionTokenEndpointAuthSigningAlgEnum(ConnectionTokenEndpointAuthSigningAlgEnum.Values.Rs384), + V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Rs512 => new ConnectionTokenEndpointAuthSigningAlgEnum(ConnectionTokenEndpointAuthSigningAlgEnum.Values.Rs512), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionTokenEndpointJwtcaAudFormatEnumOidc? ToApi(V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc? source) + { + return source switch + { + V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc.Issuer => new ConnectionTokenEndpointJwtcaAudFormatEnumOidc(ConnectionTokenEndpointJwtcaAudFormatEnumOidc.Values.Issuer), + V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc.TokenEndpoint => new ConnectionTokenEndpointJwtcaAudFormatEnumOidc(ConnectionTokenEndpointJwtcaAudFormatEnumOidc.Values.TokenEndpoint), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionDpopSigningAlgEnum? ToApi(V2alpha1ConnectionDpopSigningAlgEnum? source) + { + return source switch + { + V2alpha1ConnectionDpopSigningAlgEnum.Es256 => new ConnectionDpopSigningAlgEnum(ConnectionDpopSigningAlgEnum.Values.Es256), + V2alpha1ConnectionDpopSigningAlgEnum.Ed25519 => new ConnectionDpopSigningAlgEnum(ConnectionDpopSigningAlgEnum.Values.Ed25519), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionTypeEnumOidc? ToApi(V2alpha1ConnectionTypeEnumOidc? source) + { + return source switch + { + V2alpha1ConnectionTypeEnumOidc.BackChannel => new ConnectionTypeEnumOidc(ConnectionTypeEnumOidc.Values.BackChannel), + V2alpha1ConnectionTypeEnumOidc.FrontChannel => new ConnectionTypeEnumOidc(ConnectionTypeEnumOidc.Values.FrontChannel), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionTypeEnumOkta? ToApi(V2alpha1ConnectionTypeEnumOkta? source) + { + return source switch + { + V2alpha1ConnectionTypeEnumOkta.BackChannel => new ConnectionTypeEnumOkta(ConnectionTypeEnumOkta.Values.BackChannel), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionOptionsProtocolEnumTwitter? ToApi(V2alpha1ConnectionOptionsProtocolEnumTwitter? source) + { + return source switch + { + V2alpha1ConnectionOptionsProtocolEnumTwitter.Oauth1 => new ConnectionOptionsProtocolEnumTwitter(ConnectionOptionsProtocolEnumTwitter.Values.Oauth1), + V2alpha1ConnectionOptionsProtocolEnumTwitter.Oauth2 => new ConnectionOptionsProtocolEnumTwitter(ConnectionOptionsProtocolEnumTwitter.Values.Oauth2), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionSetUserRootAttributesEnum? ToApi(V2alpha1ConnectionSetUserRootAttributesEnum? source) + { + return source switch + { + V2alpha1ConnectionSetUserRootAttributesEnum.OnEachLogin => new ConnectionSetUserRootAttributesEnum(ConnectionSetUserRootAttributesEnum.Values.OnEachLogin), + V2alpha1ConnectionSetUserRootAttributesEnum.OnFirstLogin => new ConnectionSetUserRootAttributesEnum(ConnectionSetUserRootAttributesEnum.Values.OnFirstLogin), + V2alpha1ConnectionSetUserRootAttributesEnum.NeverOnLogin => new ConnectionSetUserRootAttributesEnum(ConnectionSetUserRootAttributesEnum.Values.NeverOnLogin), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static Optional?> ToApiUpstreamAdditionalProperties(Dictionary? source) + { + if (source is null) + return default; + + var result = new Dictionary(source.Count); + foreach (var (key, value) in source) + result[key] = value is null ? null : ToApi(value); + + return result; + } + + internal static Dictionary? ToApiUpstreamAdditionalPropertiesNonOptional(Dictionary? source) + { + if (source is null) + return null; + + var result = new Dictionary(source.Count); + foreach (var (key, value) in source) + if (value is not null) + result[key] = ToApi(value); + + return result; + } + + internal static ConnectionIdTokenSignedResponseAlgEnum ToApi(V2alpha1ConnectionIdTokenSignedResponseAlgEnum source) + { + return source switch + { + V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Es256 => new ConnectionIdTokenSignedResponseAlgEnum(ConnectionIdTokenSignedResponseAlgEnum.Values.Es256), + V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Es384 => new ConnectionIdTokenSignedResponseAlgEnum(ConnectionIdTokenSignedResponseAlgEnum.Values.Es384), + V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Ps256 => new ConnectionIdTokenSignedResponseAlgEnum(ConnectionIdTokenSignedResponseAlgEnum.Values.Ps256), + V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Ps384 => new ConnectionIdTokenSignedResponseAlgEnum(ConnectionIdTokenSignedResponseAlgEnum.Values.Ps384), + V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Rs256 => new ConnectionIdTokenSignedResponseAlgEnum(ConnectionIdTokenSignedResponseAlgEnum.Values.Rs256), + V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Rs384 => new ConnectionIdTokenSignedResponseAlgEnum(ConnectionIdTokenSignedResponseAlgEnum.Values.Rs384), + V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Rs512 => new ConnectionIdTokenSignedResponseAlgEnum(ConnectionIdTokenSignedResponseAlgEnum.Values.Rs512), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionMappingModeEnumOidc? ToApi(V2alpha1ConnectionMappingModeEnumOidc? source) + { + return source switch + { + V2alpha1ConnectionMappingModeEnumOidc.BindAll => new ConnectionMappingModeEnumOidc(ConnectionMappingModeEnumOidc.Values.BindAll), + V2alpha1ConnectionMappingModeEnumOidc.UseMap => new ConnectionMappingModeEnumOidc(ConnectionMappingModeEnumOidc.Values.UseMap), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionMappingModeEnumOkta? ToApi(V2alpha1ConnectionMappingModeEnumOkta? source) + { + return source switch + { + V2alpha1ConnectionMappingModeEnumOkta.BasicProfile => new ConnectionMappingModeEnumOkta(ConnectionMappingModeEnumOkta.Values.BasicProfile), + V2alpha1ConnectionMappingModeEnumOkta.UseMap => new ConnectionMappingModeEnumOkta(ConnectionMappingModeEnumOkta.Values.UseMap), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionConnectionSettingsPkceEnum? ToApi(V2alpha1ConnectionConnectionSettingsPkceEnum? source) + { + return source switch + { + V2alpha1ConnectionConnectionSettingsPkceEnum.Auto => new ConnectionConnectionSettingsPkceEnum(ConnectionConnectionSettingsPkceEnum.Values.Auto), + V2alpha1ConnectionConnectionSettingsPkceEnum.S256 => new ConnectionConnectionSettingsPkceEnum(ConnectionConnectionSettingsPkceEnum.Values.S256), + V2alpha1ConnectionConnectionSettingsPkceEnum.Plain => new ConnectionConnectionSettingsPkceEnum(ConnectionConnectionSettingsPkceEnum.Values.Plain), + V2alpha1ConnectionConnectionSettingsPkceEnum.Disabled => new ConnectionConnectionSettingsPkceEnum(ConnectionConnectionSettingsPkceEnum.Values.Disabled), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionSignatureAlgorithmEnumSaml ToApi(V2alpha1ConnectionSignatureAlgorithmEnumSaml source) + { + return source switch + { + V2alpha1ConnectionSignatureAlgorithmEnumSaml.RsaSha1 => new ConnectionSignatureAlgorithmEnumSaml(ConnectionSignatureAlgorithmEnumSaml.Values.RsaSha1), + V2alpha1ConnectionSignatureAlgorithmEnumSaml.RsaSha256 => new ConnectionSignatureAlgorithmEnumSaml(ConnectionSignatureAlgorithmEnumSaml.Values.RsaSha256), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionDigestAlgorithmEnumSaml ToApi(V2alpha1ConnectionDigestAlgorithmEnumSaml source) + { + return source switch + { + V2alpha1ConnectionDigestAlgorithmEnumSaml.Sha1 => new ConnectionDigestAlgorithmEnumSaml(ConnectionDigestAlgorithmEnumSaml.Values.Sha1), + V2alpha1ConnectionDigestAlgorithmEnumSaml.Sha256 => new ConnectionDigestAlgorithmEnumSaml(ConnectionDigestAlgorithmEnumSaml.Values.Sha256), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionProtocolBindingEnumSaml ToApi(V2alpha1ConnectionProtocolBindingEnumSaml source) + { + return source switch + { + V2alpha1ConnectionProtocolBindingEnumSaml.UrnOasisNamesTcSaml20BindingsHttpPost => new ConnectionProtocolBindingEnumSaml(ConnectionProtocolBindingEnumSaml.Values.UrnOasisNamesTcSaml20BindingsHttpPost), + V2alpha1ConnectionProtocolBindingEnumSaml.UrnOasisNamesTcSaml20BindingsHttpRedirect => new ConnectionProtocolBindingEnumSaml(ConnectionProtocolBindingEnumSaml.Values.UrnOasisNamesTcSaml20BindingsHttpRedirect), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionOptionsIdpInitiatedClientProtocolEnumSaml ToApi(V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml source) + { + return source switch + { + V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Oidc => new ConnectionOptionsIdpInitiatedClientProtocolEnumSaml(ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Values.Oidc), + V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Samlp => new ConnectionOptionsIdpInitiatedClientProtocolEnumSaml(ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Values.Samlp), + V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Wsfed => new ConnectionOptionsIdpInitiatedClientProtocolEnumSaml(ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Values.Wsfed), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionAssertionDecryptionAlgorithmProfileEnum ToApi(V2alpha1ConnectionAssertionDecryptionAlgorithmProfileEnum source) + { + return source switch + { + V2alpha1ConnectionAssertionDecryptionAlgorithmProfileEnum.V20261 => new ConnectionAssertionDecryptionAlgorithmProfileEnum(ConnectionAssertionDecryptionAlgorithmProfileEnum.Values.V20261), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static SignupStatusEnum ToApi(V2alpha1ConnectionOptionsAttributeStatus source) + { + return source switch + { + V2alpha1ConnectionOptionsAttributeStatus.Required => new SignupStatusEnum(SignupStatusEnum.Values.Required), + V2alpha1ConnectionOptionsAttributeStatus.Optional => new SignupStatusEnum(SignupStatusEnum.Values.Optional), + V2alpha1ConnectionOptionsAttributeStatus.Inactive => new SignupStatusEnum(SignupStatusEnum.Values.Inactive), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionPasswordPolicyEnum ToApi(V2alpha1ConnectionPasswordPolicyEnum source) + { + return source switch + { + V2alpha1ConnectionPasswordPolicyEnum.None => new ConnectionPasswordPolicyEnum(ConnectionPasswordPolicyEnum.Values.None), + V2alpha1ConnectionPasswordPolicyEnum.Low => new ConnectionPasswordPolicyEnum(ConnectionPasswordPolicyEnum.Values.Low), + V2alpha1ConnectionPasswordPolicyEnum.Fair => new ConnectionPasswordPolicyEnum(ConnectionPasswordPolicyEnum.Values.Fair), + V2alpha1ConnectionPasswordPolicyEnum.Good => new ConnectionPasswordPolicyEnum(ConnectionPasswordPolicyEnum.Values.Good), + V2alpha1ConnectionPasswordPolicyEnum.Excellent => new ConnectionPasswordPolicyEnum(ConnectionPasswordPolicyEnum.Values.Excellent), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionEmailEmailSyntax? ToApi(V2alpha1ConnectionEmailEmailSyntax? source) + { + return source switch + { + V2alpha1ConnectionEmailEmailSyntax.Liquid => new ConnectionEmailEmailSyntax(ConnectionEmailEmailSyntax.Values.Liquid), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static Dictionary? FromApi(Optional?> source) + { + if (!source.IsDefined || source.Value is not { } dict) + return null; + + var result = new Dictionary(dict.Count); + foreach (var (key, value) in dict) + if (value is not null) + result[key] = FromApi(value); + + return result.Count > 0 ? result : null; + } + + internal static Dictionary? FromApi(Dictionary? source) + { + if (source is null) + return null; + + var result = new Dictionary(source.Count); + foreach (var (key, value) in source) + if (value is not null) + result[key] = FromApi(value); + + return result.Count > 0 ? result : null; + } + + internal static V2alpha1ConnectionUpstreamAdditionalProperties FromApi(ConnectionUpstreamAdditionalProperties source) + { + if (source.TryGetConnectionUpstreamAlias(out var alias)) + { + return new V2alpha1ConnectionUpstreamAdditionalProperties + { + Alias = alias?.Alias is { } aliasValue ? FromApi(aliasValue) : null, + }; + } + + if (source.TryGetConnectionUpstreamValue(out var value)) + { + return new V2alpha1ConnectionUpstreamAdditionalProperties + { + Value = value?.Value, + }; + } + + throw new ArgumentOutOfRangeException(nameof(source), source, null); + } + + internal static ConnectionUpstreamAdditionalProperties ToApi(V2alpha1ConnectionUpstreamAdditionalProperties source) + { + if (source.Alias is { } alias) + { + return ConnectionUpstreamAdditionalProperties.FromConnectionUpstreamAlias(new ConnectionUpstreamAlias + { + Alias = ToApi(alias), + }); + } + + if (source.Value is { } value) + { + return ConnectionUpstreamAdditionalProperties.FromConnectionUpstreamValue(new ConnectionUpstreamValue + { + Value = value, + }); + } + + throw new ArgumentException("Upstream additional properties must define either Alias or Value.", nameof(source)); + } + + internal static V2alpha1ConnectionUpstreamAliasEnum FromApi(ConnectionUpstreamAliasEnum source) + { + return source.Value switch + { + "acr_values" => V2alpha1ConnectionUpstreamAliasEnum.AcrValues, + "audience" => V2alpha1ConnectionUpstreamAliasEnum.Audience, + "client_id" => V2alpha1ConnectionUpstreamAliasEnum.ClientId, + "display" => V2alpha1ConnectionUpstreamAliasEnum.Display, + "id_token_hint" => V2alpha1ConnectionUpstreamAliasEnum.IdTokenHint, + "login_hint" => V2alpha1ConnectionUpstreamAliasEnum.LoginHint, + "max_age" => V2alpha1ConnectionUpstreamAliasEnum.MaxAge, + "prompt" => V2alpha1ConnectionUpstreamAliasEnum.Prompt, + "resource" => V2alpha1ConnectionUpstreamAliasEnum.Resource, + "response_mode" => V2alpha1ConnectionUpstreamAliasEnum.ResponseMode, + "response_type" => V2alpha1ConnectionUpstreamAliasEnum.ResponseType, + "ui_locales" => V2alpha1ConnectionUpstreamAliasEnum.UiLocales, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionUpstreamAliasEnum ToApi(V2alpha1ConnectionUpstreamAliasEnum source) + { + return source switch + { + V2alpha1ConnectionUpstreamAliasEnum.AcrValues => ConnectionUpstreamAliasEnum.AcrValues, + V2alpha1ConnectionUpstreamAliasEnum.Audience => ConnectionUpstreamAliasEnum.Audience, + V2alpha1ConnectionUpstreamAliasEnum.ClientId => ConnectionUpstreamAliasEnum.ClientId, + V2alpha1ConnectionUpstreamAliasEnum.Display => ConnectionUpstreamAliasEnum.Display, + V2alpha1ConnectionUpstreamAliasEnum.IdTokenHint => ConnectionUpstreamAliasEnum.IdTokenHint, + V2alpha1ConnectionUpstreamAliasEnum.LoginHint => ConnectionUpstreamAliasEnum.LoginHint, + V2alpha1ConnectionUpstreamAliasEnum.MaxAge => ConnectionUpstreamAliasEnum.MaxAge, + V2alpha1ConnectionUpstreamAliasEnum.Prompt => ConnectionUpstreamAliasEnum.Prompt, + V2alpha1ConnectionUpstreamAliasEnum.Resource => ConnectionUpstreamAliasEnum.Resource, + V2alpha1ConnectionUpstreamAliasEnum.ResponseMode => ConnectionUpstreamAliasEnum.ResponseMode, + V2alpha1ConnectionUpstreamAliasEnum.ResponseType => ConnectionUpstreamAliasEnum.ResponseType, + V2alpha1ConnectionUpstreamAliasEnum.UiLocales => ConnectionUpstreamAliasEnum.UiLocales, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionValidationOptions FromApi(ConnectionValidationOptions source) + { + return new V2alpha1ConnectionValidationOptions + { + Username = source.Username.IsDefined && source.Username.Value is { } u ? new V2alpha1ConnectionUsernameValidationOptions + { + Min = u.Min, + Max = u.Max, + } : null, + }; + } + + internal static V2alpha1ConnectionAttributes FromApi(ConnectionAttributes source) + { + return new V2alpha1ConnectionAttributes + { + Email = source.Email is { } email ? FromApi(email) : null, + PhoneNumber = source.PhoneNumber is { } phoneNumber ? FromApi(phoneNumber) : null, + Username = source.Username is { } username ? FromApi(username) : null, + }; + } + + internal static V2alpha1ConnectionEmailAttribute FromApi(EmailAttribute source) + { + return new V2alpha1ConnectionEmailAttribute + { + Identifier = source.Identifier is { } identifier ? FromApi(identifier) : null, + Unique = source.Unique, + ProfileRequired = source.ProfileRequired, + VerificationMethod = FromApi(source.VerificationMethod), + Signup = source.Signup is { } signup ? FromApi(signup) : null, + }; + } + + internal static V2alpha1ConnectionPhoneAttribute FromApi(PhoneAttribute source) + { + return new V2alpha1ConnectionPhoneAttribute + { + Identifier = source.Identifier is { } identifier ? FromApi(identifier) : null, + ProfileRequired = source.ProfileRequired, + Signup = source.Signup is { } signup ? FromApi(signup) : null, + }; + } + + internal static V2alpha1ConnectionUsernameAttribute FromApi(UsernameAttribute source) + { + return new V2alpha1ConnectionUsernameAttribute + { + Identifier = source.Identifier is { } identifier ? FromApi(identifier) : null, + ProfileRequired = source.ProfileRequired, + Signup = source.Signup is { } signup ? FromApi(signup) : null, + Validation = source.Validation is { } validation ? FromApi(validation) : null, + }; + } + + internal static V2alpha1ConnectionAttributeIdentifier FromApi(ConnectionAttributeIdentifier source) + { + return new V2alpha1ConnectionAttributeIdentifier + { + Active = source.Active, + }; + } + + internal static V2alpha1ConnectionVerificationMethodEnum? FromApi(VerificationMethodEnum? source) + { + return source?.Value switch + { + VerificationMethodEnum.Values.Link => V2alpha1ConnectionVerificationMethodEnum.Link, + VerificationMethodEnum.Values.Otp => V2alpha1ConnectionVerificationMethodEnum.Otp, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionSignupVerified FromApi(SignupVerified source) + { + return new V2alpha1ConnectionSignupVerified + { + Status = FromApi(source.Status), + Verification = source.Verification is { } verification ? FromApi(verification) : null, + }; + } + + internal static V2alpha1ConnectionSignupSchema FromApi(SignupSchema source) + { + return new V2alpha1ConnectionSignupSchema + { + Status = FromApi(source.Status), + }; + } + + internal static V2alpha1ConnectionSignupStatusEnum? FromApi(SignupStatusEnum? source) + { + return source?.Value switch + { + SignupStatusEnum.Values.Required => V2alpha1ConnectionSignupStatusEnum.Required, + SignupStatusEnum.Values.Optional => V2alpha1ConnectionSignupStatusEnum.Optional, + SignupStatusEnum.Values.Inactive => V2alpha1ConnectionSignupStatusEnum.Inactive, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionSignupVerification FromApi(SignupVerification source) + { + return new V2alpha1ConnectionSignupVerification + { + Active = source.Active, + }; + } + + internal static V2alpha1ConnectionUsernameValidation FromApi(UsernameValidation source) + { + return new V2alpha1ConnectionUsernameValidation + { + MinLength = source.MinLength, + MaxLength = source.MaxLength, + AllowedTypes = source.AllowedTypes is { } allowedTypes ? FromApi(allowedTypes) : null, + }; + } + + internal static V2alpha1ConnectionUsernameAllowedTypes FromApi(UsernameAllowedTypes source) + { + return new V2alpha1ConnectionUsernameAllowedTypes + { + Email = source.Email, + PhoneNumber = source.PhoneNumber, + }; + } + + internal static V2alpha1ConnectionAuthenticationMethods FromApi(ConnectionAuthenticationMethods source) + { + return new V2alpha1ConnectionAuthenticationMethods + { + Password = source.Password is { } password ? FromApi(password) : null, + Passkey = source.Passkey is { } passkey ? FromApi(passkey) : null, + EmailOtp = source.EmailOtp is { } emailOtp ? FromApi(emailOtp) : null, + PhoneOtp = source.PhoneOtp is { } phoneOtp ? FromApi(phoneOtp) : null, + }; + } + + internal static V2alpha1ConnectionPasswordAuthenticationMethod FromApi(ConnectionPasswordAuthenticationMethod source) + { + return new V2alpha1ConnectionPasswordAuthenticationMethod + { + Enabled = source.Enabled, + }; + } + + internal static V2alpha1ConnectionPasskeyAuthenticationMethod FromApi(ConnectionPasskeyAuthenticationMethod source) + { + return new V2alpha1ConnectionPasskeyAuthenticationMethod + { + Enabled = source.Enabled, + }; + } + + internal static V2alpha1ConnectionEmailOtpAuthenticationMethod FromApi(ConnectionEmailOtpAuthenticationMethod source) + { + return new V2alpha1ConnectionEmailOtpAuthenticationMethod + { + Enabled = source.Enabled, + }; + } + + internal static V2alpha1ConnectionPhoneOtpAuthenticationMethod FromApi(ConnectionPhoneOtpAuthenticationMethod source) + { + return new V2alpha1ConnectionPhoneOtpAuthenticationMethod + { + Enabled = source.Enabled, + }; + } + + internal static V2alpha1ConnectionMfa FromApi(ConnectionMfa source) + { + return new V2alpha1ConnectionMfa + { + Active = source.Active, + ReturnEnrollSettings = source.ReturnEnrollSettings, + }; + } + + internal static V2alpha1ConnectionPasskeyOptions FromApi(ConnectionPasskeyOptions source) + { + return new V2alpha1ConnectionPasskeyOptions + { + ChallengeUi = FromApi(source.ChallengeUi), + ProgressiveEnrollmentEnabled = source.ProgressiveEnrollmentEnabled, + LocalEnrollmentEnabled = source.LocalEnrollmentEnabled, + }; + } + + internal static V2alpha1ConnectionPasskeyChallengeUiEnum? FromApi(ConnectionPasskeyChallengeUiEnum? source) + { + return source?.Value switch + { + ConnectionPasskeyChallengeUiEnum.Values.Both => V2alpha1ConnectionPasskeyChallengeUiEnum.Both, + ConnectionPasskeyChallengeUiEnum.Values.Autofill => V2alpha1ConnectionPasskeyChallengeUiEnum.Autofill, + ConnectionPasskeyChallengeUiEnum.Values.Button => V2alpha1ConnectionPasskeyChallengeUiEnum.Button, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionPasswordOptions FromApi(ConnectionPasswordOptions source) + { + return new V2alpha1ConnectionPasswordOptions + { + Complexity = source.Complexity is { } complexity ? FromApi(complexity) : null, + Dictionary = source.Dictionary is { } dictionary ? FromApi(dictionary) : null, + History = source.History is { } history ? FromApi(history) : null, + ProfileData = source.ProfileData is { } profileData ? FromApi(profileData) : null, + }; + } + + internal static V2alpha1ConnectionPasswordOptionsComplexity FromApi(ConnectionPasswordOptionsComplexity source) + { + return new V2alpha1ConnectionPasswordOptionsComplexity + { + MinLength = source.MinLength, + }; + } + + internal static V2alpha1ConnectionPasswordOptionsDictionary FromApi(ConnectionPasswordOptionsDictionary source) + { + return new V2alpha1ConnectionPasswordOptionsDictionary + { + Active = source.Active, + Custom = source.Custom?.ToArray(), + }; + } + + internal static V2alpha1ConnectionPasswordOptionsHistory FromApi(ConnectionPasswordOptionsHistory source) + { + return new V2alpha1ConnectionPasswordOptionsHistory + { + Active = source.Active, + Size = source.Size, + }; + } + + internal static V2alpha1ConnectionPasswordOptionsProfileData FromApi(ConnectionPasswordOptionsProfileData source) + { + return new V2alpha1ConnectionPasswordOptionsProfileData + { + Active = source.Active, + BlockedFields = source.BlockedFields?.ToArray(), + }; + } + + internal static V2alpha1ConnectionPasswordPolicyEnum? FromApi(ConnectionPasswordPolicyEnum? source) + { + return source?.Value switch + { + ConnectionPasswordPolicyEnum.Values.None => V2alpha1ConnectionPasswordPolicyEnum.None, + ConnectionPasswordPolicyEnum.Values.Low => V2alpha1ConnectionPasswordPolicyEnum.Low, + ConnectionPasswordPolicyEnum.Values.Fair => V2alpha1ConnectionPasswordPolicyEnum.Fair, + ConnectionPasswordPolicyEnum.Values.Good => V2alpha1ConnectionPasswordPolicyEnum.Good, + ConnectionPasswordPolicyEnum.Values.Excellent => V2alpha1ConnectionPasswordPolicyEnum.Excellent, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionPasswordHistoryOptions FromApi(ConnectionPasswordHistoryOptions source) + { + return new V2alpha1ConnectionPasswordHistoryOptions + { + Enable = source.Enable, + Size = source.Size, + }; + } + + internal static V2alpha1ConnectionPasswordNoPersonalInfoOptions FromApi(ConnectionPasswordNoPersonalInfoOptions source) + { + return new V2alpha1ConnectionPasswordNoPersonalInfoOptions + { + Enable = source.Enable, + }; + } + + internal static V2alpha1ConnectionPasswordDictionaryOptions FromApi(ConnectionPasswordDictionaryOptions source) + { + return new V2alpha1ConnectionPasswordDictionaryOptions + { + Enable = source.Enable, + Dictionary = source.Dictionary?.ToArray(), + }; + } + + internal static V2alpha1ConnectionPasswordComplexityOptions FromApi(ConnectionPasswordComplexityOptions source) + { + return new V2alpha1ConnectionPasswordComplexityOptions + { + MinLength = source.MinLength, + }; + } + + internal static V2alpha1ConnectionCustomScripts FromApi(ConnectionCustomScripts source) + { + return new V2alpha1ConnectionCustomScripts + { + Login = source.Login, + GetUser = source.GetUser, + Delete = source.Delete, + ChangePassword = source.ChangePassword, + Verify = source.Verify, + Create = source.Create, + ChangeUsername = source.ChangeUsername, + ChangeEmail = source.ChangeEmail, + ChangePhoneNumber = source.ChangePhoneNumber, + }; + } + + internal static V2alpha1ConnectionEmailEmailSyntax? FromApi(ConnectionEmailEmailSyntax? source) + { + return source?.Value switch + { + ConnectionEmailEmailSyntax.Values.Liquid => V2alpha1ConnectionEmailEmailSyntax.Liquid, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionSignatureMethodOAuth1? FromApi(ConnectionSignatureMethodOAuth1? source) + { + return source?.Value switch + { + ConnectionSignatureMethodOAuth1.Values.RsaSha1 => V2alpha1ConnectionSignatureMethodOAuth1.RsaSha1, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionTokenEndpointAuthMethodEnum? FromApi(ConnectionTokenEndpointAuthMethodEnum? source) + { + return source?.Value switch + { + ConnectionTokenEndpointAuthMethodEnum.Values.ClientSecretPost => V2alpha1ConnectionTokenEndpointAuthMethodEnum.ClientSecretPost, + ConnectionTokenEndpointAuthMethodEnum.Values.PrivateKeyJwt => V2alpha1ConnectionTokenEndpointAuthMethodEnum.PrivateKeyJwt, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum? FromApi(ConnectionTokenEndpointAuthSigningAlgEnum? source) + { + return source?.Value switch + { + ConnectionTokenEndpointAuthSigningAlgEnum.Values.Es256 => V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Es256, + ConnectionTokenEndpointAuthSigningAlgEnum.Values.Es384 => V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Es384, + ConnectionTokenEndpointAuthSigningAlgEnum.Values.Ps256 => V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Ps256, + ConnectionTokenEndpointAuthSigningAlgEnum.Values.Ps384 => V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Ps384, + ConnectionTokenEndpointAuthSigningAlgEnum.Values.Rs256 => V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Rs256, + ConnectionTokenEndpointAuthSigningAlgEnum.Values.Rs384 => V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Rs384, + ConnectionTokenEndpointAuthSigningAlgEnum.Values.Rs512 => V2alpha1ConnectionTokenEndpointAuthSigningAlgEnum.Rs512, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc? FromApi(ConnectionTokenEndpointJwtcaAudFormatEnumOidc? source) + { + return source?.Value switch + { + ConnectionTokenEndpointJwtcaAudFormatEnumOidc.Values.Issuer => V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc.Issuer, + ConnectionTokenEndpointJwtcaAudFormatEnumOidc.Values.TokenEndpoint => V2alpha1ConnectionTokenEndpointJwtcaAudFormatEnumOidc.TokenEndpoint, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionDpopSigningAlgEnum? FromApi(ConnectionDpopSigningAlgEnum? source) + { + return source?.Value switch + { + ConnectionDpopSigningAlgEnum.Values.Es256 => V2alpha1ConnectionDpopSigningAlgEnum.Es256, + ConnectionDpopSigningAlgEnum.Values.Ed25519 => V2alpha1ConnectionDpopSigningAlgEnum.Ed25519, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionIdTokenSignedResponseAlgEnum FromApi(ConnectionIdTokenSignedResponseAlgEnum source) + { + return source.Value switch + { + ConnectionIdTokenSignedResponseAlgEnum.Values.Es256 => V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Es256, + ConnectionIdTokenSignedResponseAlgEnum.Values.Es384 => V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Es384, + ConnectionIdTokenSignedResponseAlgEnum.Values.Ps256 => V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Ps256, + ConnectionIdTokenSignedResponseAlgEnum.Values.Ps384 => V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Ps384, + ConnectionIdTokenSignedResponseAlgEnum.Values.Rs256 => V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Rs256, + ConnectionIdTokenSignedResponseAlgEnum.Values.Rs384 => V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Rs384, + ConnectionIdTokenSignedResponseAlgEnum.Values.Rs512 => V2alpha1ConnectionIdTokenSignedResponseAlgEnum.Rs512, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionTypeEnumOidc? FromApi(ConnectionTypeEnumOidc? source) + { + return source?.Value switch + { + ConnectionTypeEnumOidc.Values.BackChannel => V2alpha1ConnectionTypeEnumOidc.BackChannel, + ConnectionTypeEnumOidc.Values.FrontChannel => V2alpha1ConnectionTypeEnumOidc.FrontChannel, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionAttributeMapOidc FromApi(ConnectionAttributeMapOidc source) + { + return new V2alpha1ConnectionAttributeMapOidc + { + MappingMode = FromApi(source.MappingMode), + UserinfoScope = source.UserinfoScope, + Attributes = source.Attributes?.ToDictionary(kv => kv.Key, kv => kv.Value), + }; + } + + internal static V2alpha1ConnectionMappingModeEnumOidc? FromApi(ConnectionMappingModeEnumOidc? source) + { + return source?.Value switch + { + ConnectionMappingModeEnumOidc.Values.BindAll => V2alpha1ConnectionMappingModeEnumOidc.BindAll, + ConnectionMappingModeEnumOidc.Values.UseMap => V2alpha1ConnectionMappingModeEnumOidc.UseMap, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionConnectionSettings FromApi(ConnectionConnectionSettings source) + { + return new V2alpha1ConnectionConnectionSettings + { + Pkce = FromApi(source.Pkce), + }; + } + + internal static V2alpha1ConnectionConnectionSettingsPkceEnum? FromApi(ConnectionConnectionSettingsPkceEnum? source) + { + return source?.Value switch + { + ConnectionConnectionSettingsPkceEnum.Values.Auto => V2alpha1ConnectionConnectionSettingsPkceEnum.Auto, + ConnectionConnectionSettingsPkceEnum.Values.S256 => V2alpha1ConnectionConnectionSettingsPkceEnum.S256, + ConnectionConnectionSettingsPkceEnum.Values.Plain => V2alpha1ConnectionConnectionSettingsPkceEnum.Plain, + ConnectionConnectionSettingsPkceEnum.Values.Disabled => V2alpha1ConnectionConnectionSettingsPkceEnum.Disabled, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionFederatedConnectionsAccessTokens FromApi(ConnectionFederatedConnectionsAccessTokens source) + { + return new V2alpha1ConnectionFederatedConnectionsAccessTokens + { + Active = source.Active, + }; + } + + internal static V2alpha1ConnectionOptionsOidcMetadata FromApi(ConnectionOptionsOidcMetadata source) + { + return new V2alpha1ConnectionOptionsOidcMetadata + { + AcrValuesSupported = source.AcrValuesSupported?.ToArray(), + AuthorizationEndpoint = source.AuthorizationEndpoint, + ClaimTypesSupported = source.ClaimTypesSupported?.ToArray(), + ClaimsLocalesSupported = source.ClaimsLocalesSupported?.ToArray(), + ClaimsParameterSupported = source.ClaimsParameterSupported, + ClaimsSupported = source.ClaimsSupported?.ToArray(), + DisplayValuesSupported = source.DisplayValuesSupported?.ToArray(), + DpopSigningAlgValuesSupported = source.DpopSigningAlgValuesSupported?.ToArray(), + EndSessionEndpoint = source.EndSessionEndpoint, + GrantTypesSupported = source.GrantTypesSupported?.ToArray(), + IdTokenEncryptionAlgValuesSupported = source.IdTokenEncryptionAlgValuesSupported?.ToArray(), + IdTokenEncryptionEncValuesSupported = source.IdTokenEncryptionEncValuesSupported?.ToArray(), + IdTokenSigningAlgValuesSupported = source.IdTokenSigningAlgValuesSupported?.ToArray(), + Issuer = source.Issuer, + JwksUri = source.JwksUri, + OpPolicyUri = source.OpPolicyUri, + OpTosUri = source.OpTosUri, + RegistrationEndpoint = source.RegistrationEndpoint, + RequestObjectEncryptionAlgValuesSupported = source.RequestObjectEncryptionAlgValuesSupported?.ToArray(), + RequestObjectEncryptionEncValuesSupported = source.RequestObjectEncryptionEncValuesSupported?.ToArray(), + RequestObjectSigningAlgValuesSupported = source.RequestObjectSigningAlgValuesSupported?.ToArray(), + RequestParameterSupported = source.RequestParameterSupported, + RequestUriParameterSupported = source.RequestUriParameterSupported, + RequireRequestUriRegistration = source.RequireRequestUriRegistration, + ResponseModesSupported = source.ResponseModesSupported?.ToArray(), + ResponseTypesSupported = source.ResponseTypesSupported?.ToArray(), + ScopesSupported = source.ScopesSupported.IsDefined && source.ScopesSupported.Value is { } scopesSupported ? scopesSupported.ToArray() : null, + ServiceDocumentation = source.ServiceDocumentation, + SubjectTypesSupported = source.SubjectTypesSupported?.ToArray(), + TokenEndpoint = source.TokenEndpoint, + TokenEndpointAuthMethodsSupported = source.TokenEndpointAuthMethodsSupported?.ToArray(), + TokenEndpointAuthSigningAlgValuesSupported = source.TokenEndpointAuthSigningAlgValuesSupported?.ToArray(), + UiLocalesSupported = source.UiLocalesSupported?.ToArray(), + UserinfoEncryptionAlgValuesSupported = source.UserinfoEncryptionAlgValuesSupported?.ToArray(), + UserinfoEncryptionEncValuesSupported = source.UserinfoEncryptionEncValuesSupported?.ToArray(), + UserinfoEndpoint = source.UserinfoEndpoint, + UserinfoSigningAlgValuesSupported = source.UserinfoSigningAlgValuesSupported?.ToArray(), + }; + } + + internal static V2alpha1ConnectionTypeEnumOkta? FromApi(ConnectionTypeEnumOkta? source) + { + return source?.Value switch + { + ConnectionTypeEnumOkta.Values.BackChannel => V2alpha1ConnectionTypeEnumOkta.BackChannel, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionAttributeMapOkta FromApi(ConnectionAttributeMapOkta source) + { + return new V2alpha1ConnectionAttributeMapOkta + { + MappingMode = FromApi(source.MappingMode), + UserinfoScope = source.UserinfoScope, + Attributes = source.Attributes?.ToDictionary(kv => kv.Key, kv => kv.Value), + }; + } + + internal static V2alpha1ConnectionMappingModeEnumOkta? FromApi(ConnectionMappingModeEnumOkta? source) + { + return source?.Value switch + { + ConnectionMappingModeEnumOkta.Values.BasicProfile => V2alpha1ConnectionMappingModeEnumOkta.BasicProfile, + ConnectionMappingModeEnumOkta.Values.UseMap => V2alpha1ConnectionMappingModeEnumOkta.UseMap, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionSignatureAlgorithmEnumSaml? FromApi(ConnectionSignatureAlgorithmEnumSaml? source) + { + return source?.Value switch + { + ConnectionSignatureAlgorithmEnumSaml.Values.RsaSha1 => V2alpha1ConnectionSignatureAlgorithmEnumSaml.RsaSha1, + ConnectionSignatureAlgorithmEnumSaml.Values.RsaSha256 => V2alpha1ConnectionSignatureAlgorithmEnumSaml.RsaSha256, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionDigestAlgorithmEnumSaml? FromApi(ConnectionDigestAlgorithmEnumSaml? source) + { + return source?.Value switch + { + ConnectionDigestAlgorithmEnumSaml.Values.Sha1 => V2alpha1ConnectionDigestAlgorithmEnumSaml.Sha1, + ConnectionDigestAlgorithmEnumSaml.Values.Sha256 => V2alpha1ConnectionDigestAlgorithmEnumSaml.Sha256, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionProtocolBindingEnumSaml? FromApi(ConnectionProtocolBindingEnumSaml? source) + { + return source?.Value switch + { + ConnectionProtocolBindingEnumSaml.Values.UrnOasisNamesTcSaml20BindingsHttpPost => V2alpha1ConnectionProtocolBindingEnumSaml.UrnOasisNamesTcSaml20BindingsHttpPost, + ConnectionProtocolBindingEnumSaml.Values.UrnOasisNamesTcSaml20BindingsHttpRedirect => V2alpha1ConnectionProtocolBindingEnumSaml.UrnOasisNamesTcSaml20BindingsHttpRedirect, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionOptionsIdpinitiatedSaml FromApi(ConnectionOptionsIdpinitiatedSaml source) + { + return new V2alpha1ConnectionOptionsIdpinitiatedSaml + { + ClientId = source.ClientId, + ClientProtocol = FromApi(source.ClientProtocol), + ClientAuthorizequery = source.ClientAuthorizequery, + Enabled = source.Enabled, + }; + } + + internal static V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml? FromApi(ConnectionOptionsIdpInitiatedClientProtocolEnumSaml? source) + { + return source?.Value switch + { + ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Values.Oidc => V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Oidc, + ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Values.Samlp => V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Samlp, + ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Values.Wsfed => V2alpha1ConnectionOptionsIdpInitiatedClientProtocolEnumSaml.Wsfed, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionAssertionDecryptionSettings FromApi(ConnectionAssertionDecryptionSettings source) + { + return new V2alpha1ConnectionAssertionDecryptionSettings + { + AlgorithmProfile = FromApi(source.AlgorithmProfile), + AlgorithmExceptions = source.AlgorithmExceptions?.ToArray(), + }; + } + + internal static V2alpha1ConnectionAssertionDecryptionAlgorithmProfileEnum FromApi(ConnectionAssertionDecryptionAlgorithmProfileEnum source) + { + return source.Value switch + { + ConnectionAssertionDecryptionAlgorithmProfileEnum.Values.V20261 => V2alpha1ConnectionAssertionDecryptionAlgorithmProfileEnum.V20261, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionTemplateSyntaxEnumSms? FromApi(ConnectionTemplateSyntaxEnumSms? source) + { + return source?.Value switch + { + ConnectionTemplateSyntaxEnumSms.Values.Liquid => V2alpha1ConnectionTemplateSyntaxEnumSms.Liquid, + ConnectionTemplateSyntaxEnumSms.Values.MdWithMacros => V2alpha1ConnectionTemplateSyntaxEnumSms.MdWithMacros, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionProviderEnumSms? FromApi(ConnectionProviderEnumSms? source) + { + return source?.Value switch + { + ConnectionProviderEnumSms.Values.SmsGateway => V2alpha1ConnectionProviderEnumSms.SmsGateway, + ConnectionProviderEnumSms.Values.Twilio => V2alpha1ConnectionProviderEnumSms.Twilio, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionGatewayAuthenticationSms FromApi(ConnectionGatewayAuthenticationSms source) + { + return new V2alpha1ConnectionGatewayAuthenticationSms + { + Method = source.Method, + Subject = source.Subject, + Audience = source.Audience, + Secret = source.Secret, + SecretBase64Encoded = source.SecretBase64Encoded, + }; + } + + internal static V2alpha1ConnectionOptionsProtocolEnumTwitter? FromApi(ConnectionOptionsProtocolEnumTwitter? source) + { + return source?.Value switch + { + ConnectionOptionsProtocolEnumTwitter.Values.Oauth1 => V2alpha1ConnectionOptionsProtocolEnumTwitter.Oauth1, + ConnectionOptionsProtocolEnumTwitter.Values.Oauth2 => V2alpha1ConnectionOptionsProtocolEnumTwitter.Oauth2, + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionOptionsUserName FromApi(ConnectionUsernameValidationOptions source) + { + return new V2alpha1ConnectionOptionsUserName + { + Min = source.Min, + Max = source.Max, + }; + } + + internal static V2alpha1ConnectionGatewayAuthentication FromApi(ConnectionGatewayAuthentication source) + { + return new V2alpha1ConnectionGatewayAuthentication + { + Method = source.Method, + Subject = source.Subject, + Audience = source.Audience, + Secret = source.Secret, + SecretBase64Encoded = source.SecretBase64Encoded, + }; + } + + internal static V2alpha1ConnectionOptionsPrecedence FromApi(ConnectionIdentifierPrecedenceEnum source) + { + return source.Value switch + { + ConnectionIdentifierPrecedenceEnum.Values.Email => V2alpha1ConnectionOptionsPrecedence.Email, + ConnectionIdentifierPrecedenceEnum.Values.PhoneNumber => V2alpha1ConnectionOptionsPrecedence.PhoneNumber, + ConnectionIdentifierPrecedenceEnum.Values.Username => V2alpha1ConnectionOptionsPrecedence.UserName, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionIdentifierPrecedenceEnum ToApi(V2alpha1ConnectionOptionsPrecedence source) + { + return source switch + { + V2alpha1ConnectionOptionsPrecedence.Email => new ConnectionIdentifierPrecedenceEnum(ConnectionIdentifierPrecedenceEnum.Values.Email), + V2alpha1ConnectionOptionsPrecedence.PhoneNumber => new ConnectionIdentifierPrecedenceEnum(ConnectionIdentifierPrecedenceEnum.Values.PhoneNumber), + V2alpha1ConnectionOptionsPrecedence.UserName => new ConnectionIdentifierPrecedenceEnum(ConnectionIdentifierPrecedenceEnum.Values.Username), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionIdentifierPrecedenceEnum ToApi(V2alpha1ConnectionIdentifierPrecedenceEnum source) + { + return source switch + { + V2alpha1ConnectionIdentifierPrecedenceEnum.Email => new ConnectionIdentifierPrecedenceEnum(ConnectionIdentifierPrecedenceEnum.Values.Email), + V2alpha1ConnectionIdentifierPrecedenceEnum.PhoneNumber => new ConnectionIdentifierPrecedenceEnum(ConnectionIdentifierPrecedenceEnum.Values.PhoneNumber), + V2alpha1ConnectionIdentifierPrecedenceEnum.Username => new ConnectionIdentifierPrecedenceEnum(ConnectionIdentifierPrecedenceEnum.Values.Username), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static V2alpha1ConnectionChallengeUi FromApi(ConnectionPasskeyChallengeUiEnum source) + { + return source.Value switch + { + ConnectionPasskeyChallengeUiEnum.Values.Both => V2alpha1ConnectionChallengeUi.Both, + ConnectionPasskeyChallengeUiEnum.Values.Autofill => V2alpha1ConnectionChallengeUi.AutoFill, + ConnectionPasskeyChallengeUiEnum.Values.Button => V2alpha1ConnectionChallengeUi.Button, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionPasskeyChallengeUiEnum ToApi(V2alpha1ConnectionChallengeUi source) + { + return source switch + { + V2alpha1ConnectionChallengeUi.Both => new ConnectionPasskeyChallengeUiEnum(ConnectionPasskeyChallengeUiEnum.Values.Both), + V2alpha1ConnectionChallengeUi.AutoFill => new ConnectionPasskeyChallengeUiEnum(ConnectionPasskeyChallengeUiEnum.Values.Autofill), + V2alpha1ConnectionChallengeUi.Button => new ConnectionPasskeyChallengeUiEnum(ConnectionPasskeyChallengeUiEnum.Values.Button), + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionSetUserRootAttributesEnum? ToApi(V2alpha1ConnectionSetUserRootAttributes? source) + { + return source switch + { + V2alpha1ConnectionSetUserRootAttributes.OnEachLogin => new ConnectionSetUserRootAttributesEnum(ConnectionSetUserRootAttributesEnum.Values.OnEachLogin), + V2alpha1ConnectionSetUserRootAttributes.OnFirstLogin => new ConnectionSetUserRootAttributesEnum(ConnectionSetUserRootAttributesEnum.Values.OnFirstLogin), + V2alpha1ConnectionSetUserRootAttributes.NeverOnLogin => new ConnectionSetUserRootAttributesEnum(ConnectionSetUserRootAttributesEnum.Values.NeverOnLogin), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static ConnectionAttributes ToApi(V2alpha1ConnectionAttributes source) + { + return new ConnectionAttributes + { + Email = source.Email is { } email ? ToApi(email) : null, + PhoneNumber = source.PhoneNumber is { } phoneNumber ? ToApi(phoneNumber) : null, + Username = source.Username is { } username ? ToApi(username) : null, + }; + } + + internal static EmailAttribute ToApi(V2alpha1ConnectionEmailAttribute source) + { + return new EmailAttribute + { + Identifier = source.Identifier is { } identifier ? ToApi(identifier) : null, + Unique = source.Unique, + ProfileRequired = source.ProfileRequired, + VerificationMethod = ToApi(source.VerificationMethod), + Signup = source.Signup is { } signup ? ToApi(signup) : null, + }; + } + + internal static PhoneAttribute ToApi(V2alpha1ConnectionPhoneAttribute source) + { + return new PhoneAttribute + { + Identifier = source.Identifier is { } identifier ? ToApi(identifier) : null, + ProfileRequired = source.ProfileRequired, + Signup = source.Signup is { } signup ? ToApi(signup) : null, + }; + } + + internal static UsernameAttribute ToApi(V2alpha1ConnectionUsernameAttribute source) + { + return new UsernameAttribute + { + Identifier = source.Identifier is { } identifier ? ToApi(identifier) : null, + ProfileRequired = source.ProfileRequired, + Signup = source.Signup is { } signup ? ToApi(signup) : null, + Validation = source.Validation is { } validation ? ToApi(validation) : null, + }; + } + + internal static ConnectionAttributeIdentifier ToApi(V2alpha1ConnectionAttributeIdentifier source) + { + return new ConnectionAttributeIdentifier + { + Active = source.Active, + }; + } + + internal static VerificationMethodEnum? ToApi(V2alpha1ConnectionVerificationMethodEnum? source) + { + return source switch + { + V2alpha1ConnectionVerificationMethodEnum.Link => new VerificationMethodEnum(VerificationMethodEnum.Values.Link), + V2alpha1ConnectionVerificationMethodEnum.Otp => new VerificationMethodEnum(VerificationMethodEnum.Values.Otp), + null => null, + _ => throw new ArgumentOutOfRangeException(nameof(source), source, null), + }; + } + + internal static SignupVerified ToApi(V2alpha1ConnectionSignupVerified source) + { + return new SignupVerified + { + Status = source.Status is { } status ? ToApi(status) : null, + Verification = source.Verification is { } verification ? ToApi(verification) : null, + }; + } + + internal static SignupSchema ToApi(V2alpha1ConnectionSignupSchema source) + { + return new SignupSchema + { + Status = source.Status is { } status ? ToApi(status) : null, + }; + } + + internal static SignupVerification ToApi(V2alpha1ConnectionSignupVerification source) + { + return new SignupVerification + { + Active = source.Active, + }; + } + + internal static UsernameValidation ToApi(V2alpha1ConnectionUsernameValidation source) + { + return new UsernameValidation + { + MinLength = source.MinLength, + MaxLength = source.MaxLength, + AllowedTypes = source.AllowedTypes is { } allowedTypes ? ToApi(allowedTypes) : null, + }; + } + + internal static UsernameAllowedTypes ToApi(V2alpha1ConnectionUsernameAllowedTypes source) + { + return new UsernameAllowedTypes + { + Email = source.Email, + PhoneNumber = source.PhoneNumber, + }; + } + + internal static ConnectionAuthenticationMethods ToApi(V2alpha1ConnectionAuthenticationMethods source) + { + return new ConnectionAuthenticationMethods + { + Password = source.Password is { } password ? ToApi(password) : null, + Passkey = source.Passkey is { } passkey ? ToApi(passkey) : null, + EmailOtp = source.EmailOtp is { } emailOtp ? ToApi(emailOtp) : null, + PhoneOtp = source.PhoneOtp is { } phoneOtp ? ToApi(phoneOtp) : null, + }; + } + + internal static ConnectionPasswordAuthenticationMethod ToApi(V2alpha1ConnectionPasswordAuthenticationMethod source) + { + return new ConnectionPasswordAuthenticationMethod + { + Enabled = source.Enabled, + }; + } + + internal static ConnectionPasskeyAuthenticationMethod ToApi(V2alpha1ConnectionPasskeyAuthenticationMethod source) + { + return new ConnectionPasskeyAuthenticationMethod + { + Enabled = source.Enabled, + }; + } + + internal static ConnectionEmailOtpAuthenticationMethod ToApi(V2alpha1ConnectionEmailOtpAuthenticationMethod source) + { + return new ConnectionEmailOtpAuthenticationMethod + { + Enabled = source.Enabled, + }; + } + + internal static ConnectionPhoneOtpAuthenticationMethod ToApi(V2alpha1ConnectionPhoneOtpAuthenticationMethod source) + { + return new ConnectionPhoneOtpAuthenticationMethod + { + Enabled = source.Enabled, + }; + } + + internal static ConnectionPasskeyOptions ToApi(V2alpha1ConnectionPasskeyOptions source) + { + return new ConnectionPasskeyOptions + { + ChallengeUi = source.ChallengeUi is { } challengeUi ? ToApi(challengeUi) : null, + ProgressiveEnrollmentEnabled = source.ProgressiveEnrollmentEnabled, + LocalEnrollmentEnabled = source.LocalEnrollmentEnabled, + }; + } + + internal static ConnectionPasswordOptions ToApi(V2alpha1ConnectionPasswordOptions source) + { + return new ConnectionPasswordOptions + { + Complexity = source.Complexity is { } complexity ? ToApi(complexity) : null, + Dictionary = source.Dictionary is { } dictionary ? ToApi(dictionary) : null, + History = source.History is { } history ? ToApi(history) : null, + ProfileData = source.ProfileData is { } profileData ? ToApi(profileData) : null, + }; + } + + internal static ConnectionPasswordOptionsComplexity ToApi(V2alpha1ConnectionPasswordOptionsComplexity source) + { + return new ConnectionPasswordOptionsComplexity + { + MinLength = source.MinLength, + }; + } + + internal static ConnectionPasswordOptionsDictionary ToApi(V2alpha1ConnectionPasswordOptionsDictionary source) + { + return new ConnectionPasswordOptionsDictionary + { + Active = source.Active, + Custom = source.Custom, + }; + } + + internal static ConnectionPasswordOptionsHistory ToApi(V2alpha1ConnectionPasswordOptionsHistory source) + { + return new ConnectionPasswordOptionsHistory + { + Active = source.Active, + Size = source.Size, + }; + } + + internal static ConnectionPasswordOptionsProfileData ToApi(V2alpha1ConnectionPasswordOptionsProfileData source) + { + return new ConnectionPasswordOptionsProfileData + { + Active = source.Active, + BlockedFields = source.BlockedFields, + }; + } + + internal static ConnectionPasswordHistoryOptions ToApi(V2alpha1ConnectionPasswordHistoryOptions source) + { + return new ConnectionPasswordHistoryOptions + { + Enable = source.Enable ?? false, + Size = source.Size, + }; + } + + internal static ConnectionPasswordNoPersonalInfoOptions ToApi(V2alpha1ConnectionPasswordNoPersonalInfoOptions source) + { + return new ConnectionPasswordNoPersonalInfoOptions + { + Enable = source.Enable ?? false, + }; + } + + internal static ConnectionPasswordDictionaryOptions ToApi(V2alpha1ConnectionPasswordDictionaryOptions source) + { + return new ConnectionPasswordDictionaryOptions + { + Enable = source.Enable ?? false, + Dictionary = source.Dictionary, + }; + } + + internal static ConnectionPasswordComplexityOptions ToApi(V2alpha1ConnectionPasswordComplexityOptions source) + { + return new ConnectionPasswordComplexityOptions + { + MinLength = source.MinLength, + }; + } + + internal static ConnectionValidationOptions ToApi(V2alpha1ConnectionValidationOptions source) + { + var target = new ConnectionValidationOptions(); + if (source.Username is { } username) + target.Username = ToApi(username); + + return target; + } + + internal static ConnectionUsernameValidationOptions ToApi(V2alpha1ConnectionUsernameValidationOptions source) + { + return new ConnectionUsernameValidationOptions + { + Min = source.Min ?? 0, + Max = source.Max ?? 0, + }; + } + + internal static ConnectionMfa ToApi(V2alpha1ConnectionMfa source) + { + return new ConnectionMfa + { + Active = source.Active, + ReturnEnrollSettings = source.ReturnEnrollSettings, + }; + } + + internal static ConnectionFederatedConnectionsAccessTokens ToApi(V2alpha1ConnectionFederatedConnectionsAccessTokens source) + { + return new ConnectionFederatedConnectionsAccessTokens + { + Active = source.Active, + }; + } + + internal static ConnectionOptionsOidcMetadata ToApi(V2alpha1ConnectionOptionsOidcMetadata source) + { + return new ConnectionOptionsOidcMetadata + { + AcrValuesSupported = source.AcrValuesSupported, + AuthorizationEndpoint = source.AuthorizationEndpoint, + ClaimTypesSupported = source.ClaimTypesSupported, + ClaimsLocalesSupported = source.ClaimsLocalesSupported, + ClaimsParameterSupported = source.ClaimsParameterSupported, + ClaimsSupported = source.ClaimsSupported, + DisplayValuesSupported = source.DisplayValuesSupported, + DpopSigningAlgValuesSupported = source.DpopSigningAlgValuesSupported, + EndSessionEndpoint = source.EndSessionEndpoint, + GrantTypesSupported = source.GrantTypesSupported, + IdTokenEncryptionAlgValuesSupported = source.IdTokenEncryptionAlgValuesSupported, + IdTokenEncryptionEncValuesSupported = source.IdTokenEncryptionEncValuesSupported, + IdTokenSigningAlgValuesSupported = source.IdTokenSigningAlgValuesSupported, + Issuer = source.Issuer, + JwksUri = source.JwksUri, + OpPolicyUri = source.OpPolicyUri, + OpTosUri = source.OpTosUri, + RegistrationEndpoint = source.RegistrationEndpoint, + RequestObjectEncryptionAlgValuesSupported = source.RequestObjectEncryptionAlgValuesSupported, + RequestObjectEncryptionEncValuesSupported = source.RequestObjectEncryptionEncValuesSupported, + RequestObjectSigningAlgValuesSupported = source.RequestObjectSigningAlgValuesSupported, + RequestParameterSupported = source.RequestParameterSupported, + RequestUriParameterSupported = source.RequestUriParameterSupported, + RequireRequestUriRegistration = source.RequireRequestUriRegistration, + ResponseModesSupported = source.ResponseModesSupported, + ResponseTypesSupported = source.ResponseTypesSupported, + ServiceDocumentation = source.ServiceDocumentation, + SubjectTypesSupported = source.SubjectTypesSupported, + TokenEndpoint = source.TokenEndpoint, + TokenEndpointAuthMethodsSupported = source.TokenEndpointAuthMethodsSupported, + TokenEndpointAuthSigningAlgValuesSupported = source.TokenEndpointAuthSigningAlgValuesSupported, + UiLocalesSupported = source.UiLocalesSupported, + UserinfoEncryptionAlgValuesSupported = source.UserinfoEncryptionAlgValuesSupported, + UserinfoEncryptionEncValuesSupported = source.UserinfoEncryptionEncValuesSupported, + UserinfoEndpoint = source.UserinfoEndpoint, + UserinfoSigningAlgValuesSupported = source.UserinfoSigningAlgValuesSupported, + ScopesSupported = source.ScopesSupported is { } scopesSupported ? Optional?>.Of(scopesSupported) : default, + }; + } + + internal static Optional?> ToApi(IEnumerable source) + { + return Optional?>.Of(source.Select(ToApi)); + } + + internal static ConnectionAttributeMapOidc ToApi(V2alpha1ConnectionAttributeMapOidc source) + { + return new ConnectionAttributeMapOidc + { + MappingMode = ToApi(source.MappingMode), + UserinfoScope = source.UserinfoScope, + Attributes = source.Attributes?.Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value), + }; + } + + internal static ConnectionConnectionSettings ToApi(V2alpha1ConnectionConnectionSettings source) + { + return new ConnectionConnectionSettings + { + Pkce = ToApi(source.Pkce), + }; + } + + internal static ConnectionAttributeMapOkta ToApi(V2alpha1ConnectionAttributeMapOkta source) + { + return new ConnectionAttributeMapOkta + { + MappingMode = ToApi(source.MappingMode), + UserinfoScope = source.UserinfoScope, + Attributes = source.Attributes?.Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value), + }; + } + + internal static ConnectionOptionsIdpinitiatedSaml ToApi(V2alpha1ConnectionOptionsIdpinitiatedSaml source) + { + return new ConnectionOptionsIdpinitiatedSaml + { + ClientId = source.ClientId, + ClientProtocol = source.ClientProtocol is { } clientProtocol ? ToApi(clientProtocol) : null, + ClientAuthorizequery = source.ClientAuthorizequery, + }; + } + + internal static ConnectionAssertionDecryptionSettings? ToApi(V2alpha1ConnectionAssertionDecryptionSettings source) + { + if (source.AlgorithmProfile is not { } algorithmProfile) + return null; + + return new ConnectionAssertionDecryptionSettings + { + AlgorithmProfile = ToApi(algorithmProfile), + AlgorithmExceptions = source.AlgorithmExceptions, + }; + } + + internal static ConnectionSigningKeySaml ToApi(V2alpha1ConnectionSigningKeySaml source) + { + return new ConnectionSigningKeySaml + { + Key = source.Key, + Cert = source.Cert, + }; + } + + internal static ConnectionGatewayAuthenticationSms ToApi(V2alpha1ConnectionGatewayAuthenticationSms source) + { + var target = new ConnectionGatewayAuthenticationSms + { + Method = source.Method ?? string.Empty, + Audience = source.Audience ?? string.Empty, + Secret = source.Secret ?? string.Empty, + }; + + if (source.Subject is { } subject) + target.Subject = subject; + + if (source.SecretBase64Encoded is { } secretBase64Encoded) + target.SecretBase64Encoded = secretBase64Encoded; + + return target; + } + + internal static ConnectionOptionsAuth0 ToApi(V2alpha1ConnectionOptionsAuth0 source) + { + var target = new ConnectionOptionsAuth0(); + if (source.Attributes is { } attributes) + target.Attributes = ToApi(attributes); + if (source.AuthenticationMethods is { } authenticationMethods) + target.AuthenticationMethods = ToApi(authenticationMethods); + target.BruteForceProtection = source.BruteForceProtection; + if (source.Configuration is { } configuration) + target.Configuration = configuration.ToDictionary(kv => kv.Key, kv => kv.Value); + target.DisableSelfServiceChangePassword = source.DisableSelfServiceChangePassword; + target.DisableSignup = source.DisableSignup; + target.EnableScriptContext = source.EnableScriptContext; + target.EnabledDatabaseCustomization = source.EnabledDatabaseCustomization; + target.ImportMode = source.ImportMode; + if (source.PasskeyOptions is { } passkeyOptions) + target.PasskeyOptions = ToApi(passkeyOptions); + if (source.PasswordOptions is { } passwordOptions) + target.PasswordOptions = ToApi(passwordOptions); + if (source.Precedence is { } precedence) + target.Precedence = precedence.Select(i => ToApi(i)).ToArray(); + target.RealmFallback = source.RealmFallback; + target.RequiresUsername = source.RequiresUsername; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.PasswordPolicy is { } pp) + target.PasswordPolicy = ToApi(pp); + if (source.PasswordHistory is { } ph) + target.PasswordHistory = ToApi(ph); + if (source.PasswordNoPersonalInfo is { } pnpi) + target.PasswordNoPersonalInfo = ToApi(pnpi); + if (source.PasswordDictionary is { } pd) + target.PasswordDictionary = ToApi(pd); + if (source.PasswordComplexityOptions is { } pco) + target.PasswordComplexityOptions = ToApi(pco); + if (source.Validation is { } val) + target.Validation = ToApi(val); + if (source.CustomScripts is { } cs) { target.CustomScripts ??= new ConnectionCustomScripts(); ApplyToApi(cs, target.CustomScripts); } + if (source.Mfa is { } mfa) + target.Mfa = ToApi(mfa); + return target; + } + + internal static ConnectionOptionsAd ToApi(V2alpha1ConnectionOptionsAd source) + { + var target = new ConnectionOptionsAd(); + target.AgentIp = source.AgentIp; + target.AgentMode = source.AgentMode; + target.AgentVersion = source.AgentVersion; + target.BruteForceProtection = source.BruteForceProtection; + target.CertAuth = source.CertAuth; + if (source.Certs is { } certs) + target.Certs = certs; + target.DisableCache = source.DisableCache; + target.DisableSelfServiceChangePassword = source.DisableSelfServiceChangePassword; + if (source.DomainAliases is { } da) + target.DomainAliases = da; + target.IconUrl = source.IconUrl; + if (source.Ips is { } ips) + target.Ips = ips; + target.SignInEndpoint = source.SignInEndpoint; + target.TenantDomain = source.TenantDomain; + if (source.Thumbprints is { } tp) + target.Thumbprints = tp; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.Kerberos is { } kb) + target.Kerberos = kb; + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsAdfs ToApi(V2alpha1ConnectionOptionsAdfs source) + { + var target = new ConnectionOptionsAdfs(); + target.AdfsServer = source.AdfsServer; + if (source.DomainAliases is { } da) + target.DomainAliases = da; + target.EntityId = source.EntityId; + target.FedMetadataXml = source.FedMetadataXml; + target.IconUrl = source.IconUrl; + if (source.PrevThumbprints is { } pt) + target.PrevThumbprints = pt; + if (source.ShouldTrustEmailVerifiedConnection is not null) + target.ShouldTrustEmailVerifiedConnection = ToApi(source.ShouldTrustEmailVerifiedConnection); + target.SignInEndpoint = source.SignInEndpoint; + target.TenantDomain = source.TenantDomain; + if (source.Thumbprints is { } tp) + target.Thumbprints = tp; + target.UserIdAttribute = source.UserIdAttribute; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsAuth0Oidc ToApi(V2alpha1ConnectionOptionsAuth0Oidc source) + { + var target = new ConnectionOptionsAuth0Oidc(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + return target; + } + + internal static ConnectionOptionsAzureAd ToApi(V2alpha1ConnectionOptionsAzureAd source) + { + var target = new ConnectionOptionsAzureAd { ClientId = source.ClientId, ClientSecret = source.ClientSecret }; + target.ApiEnableUsers = source.ApiEnableUsers; + target.AppDomain = source.AppDomain; + target.AppId = source.AppId; + target.BasicProfile = source.BasicProfile; + if (source.DomainAliases is { } da) + target.DomainAliases = da; + target.ExtAccessToken = source.ExtAccessToken; + target.ExtAccountEnabled = source.ExtAccountEnabled; + target.ExtAdmin = source.ExtAdmin; + target.ExtAgreedTerms = source.ExtAgreedTerms; + target.ExtAssignedLicenses = source.ExtAssignedLicenses; + target.ExtAssignedPlans = source.ExtAssignedPlans; + target.ExtAzureId = source.ExtAzureId; + target.ExtCity = source.ExtCity; + target.ExtCountry = source.ExtCountry; + target.ExtDepartment = source.ExtDepartment; + target.ExtDirSyncEnabled = source.ExtDirSyncEnabled; + target.ExtEmail = source.ExtEmail; + target.ExtExpiresIn = source.ExtExpiresIn; + target.ExtFamilyName = source.ExtFamilyName; + target.ExtFax = source.ExtFax; + target.ExtGivenName = source.ExtGivenName; + target.ExtGroupIds = source.ExtGroupIds; + target.ExtGroups = source.ExtGroups; + target.ExtIsSuspended = source.ExtIsSuspended; + target.ExtJobTitle = source.ExtJobTitle; + target.ExtLastSync = source.ExtLastSync; + target.ExtMobile = source.ExtMobile; + target.ExtName = source.ExtName; + target.ExtNestedGroups = source.ExtNestedGroups; + target.ExtNickname = source.ExtNickname; + target.ExtOid = source.ExtOid; + target.ExtPhone = source.ExtPhone; + target.ExtPhysicalDeliveryOfficeName = source.ExtPhysicalDeliveryOfficeName; + target.ExtPostalCode = source.ExtPostalCode; + target.ExtPreferredLanguage = source.ExtPreferredLanguage; + target.ExtProfile = source.ExtProfile; + target.ExtProvisionedPlans = source.ExtProvisionedPlans; + target.ExtProvisioningErrors = source.ExtProvisioningErrors; + target.ExtProxyAddresses = source.ExtProxyAddresses; + target.ExtPuid = source.ExtPuid; + target.ExtRefreshToken = source.ExtRefreshToken; + target.ExtRoles = source.ExtRoles; + target.ExtState = source.ExtState; + target.ExtStreet = source.ExtStreet; + target.ExtTelephoneNumber = source.ExtTelephoneNumber; + target.ExtTenantid = source.ExtTenantid; + target.ExtUpn = source.ExtUpn; + target.ExtUsageLocation = source.ExtUsageLocation; + target.ExtUserId = source.ExtUserId; + if (source.FederatedConnectionsAccessTokens is { } federatedConnectionsAccessTokens) + target.FederatedConnectionsAccessTokens = ToApi(federatedConnectionsAccessTokens); + target.Granted = source.Granted; + target.IconUrl = source.IconUrl; + if (source.IdentityApi is not null) + target.IdentityApi = ToApi(source.IdentityApi); + target.MaxGroupsToRetrieve = source.MaxGroupsToRetrieve; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.ShouldTrustEmailVerifiedConnection is not null) + target.ShouldTrustEmailVerifiedConnection = ToApi(source.ShouldTrustEmailVerifiedConnection); + target.TenantDomain = source.TenantDomain; + target.TenantId = source.TenantId; + if (source.Thumbprints is { } tp) + target.Thumbprints = tp; + target.UseCommonEndpoint = source.UseCommonEndpoint; + target.UseWsfed = source.UseWsfed; + if (source.UseridAttribute is not null) + target.UseridAttribute = ToApi(source.UseridAttribute); + if (source.WaadProtocol is not null) + target.WaadProtocol = ToApi(source.WaadProtocol); + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsBitbucket ToApi(V2alpha1ConnectionOptionsBitbucket source) + { + var target = new ConnectionOptionsBitbucket(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.FreeformScopes is { } ffs) + target.FreeformScopes = ffs; + target.Profile = source.Profile; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + return target; + } + + internal static ConnectionOptionsBox ToApi(V2alpha1ConnectionOptionsBox source) + { + var target = new ConnectionOptionsBox(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsDropbox ToApi(V2alpha1ConnectionOptionsDropbox source) + { + var target = new ConnectionOptionsDropbox(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsEmail ToApi(V2alpha1ConnectionOptionsEmail source) + { + return new ConnectionOptionsEmail + { + Name = source.Name ?? string.Empty, + BruteForceProtection = source.BruteForceProtection ?? false, + Email = source.Email is { } e ? new ConnectionEmailEmail + { + From = e.From, + Subject = e.Subject, + Body = e.Body, + Syntax = ToApi(e.Syntax), + } : new ConnectionEmailEmail(), + Totp = source.Totp is { } t ? new ConnectionTotpEmail + { + Length = t.Length, + TimeStep = t.TimeStep, + } : null, + DisableSignup = source.DisableSignup, + NonPersistentAttrs = source.NonPersistentAttrs, + }; + } + + internal static ConnectionOptionsEvernote ToApi(V2alpha1ConnectionOptionsEvernote source) + { + var target = new ConnectionOptionsEvernote(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsExact ToApi(V2alpha1ConnectionOptionsExact source) + { + var target = new ConnectionOptionsExact(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsFacebook ToApi(V2alpha1ConnectionOptionsFacebook source) + { + var target = new ConnectionOptionsFacebook(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.FreeformScopes is { } ffs) + target.FreeformScopes = ffs; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + target.AdsManagement = source.AdsManagement; + target.AdsRead = source.AdsRead; + target.AllowContextProfileField = source.AllowContextProfileField; + target.BusinessManagement = source.BusinessManagement; + target.Email = source.Email; + target.GroupsAccessMemberInfo = source.GroupsAccessMemberInfo; + target.LeadsRetrieval = source.LeadsRetrieval; + target.ManageNotifications = source.ManageNotifications; + target.ManagePages = source.ManagePages; + target.PagesManageCta = source.PagesManageCta; + target.PagesManageInstantArticles = source.PagesManageInstantArticles; + target.PagesMessaging = source.PagesMessaging; + target.PagesMessagingPhoneNumber = source.PagesMessagingPhoneNumber; + target.PagesMessagingSubscriptions = source.PagesMessagingSubscriptions; + target.PagesShowList = source.PagesShowList; + target.PublicProfile = source.PublicProfile; + target.PublishActions = source.PublishActions; + target.PublishPages = source.PublishPages; + target.PublishToGroups = source.PublishToGroups; + target.PublishVideo = source.PublishVideo; + target.ReadAudienceNetworkInsights = source.ReadAudienceNetworkInsights; + target.ReadInsights = source.ReadInsights; + target.ReadMailbox = source.ReadMailbox; + target.ReadPageMailboxes = source.ReadPageMailboxes; + target.ReadStream = source.ReadStream; + target.UserAgeRange = source.UserAgeRange; + target.UserBirthday = source.UserBirthday; + target.UserEvents = source.UserEvents; + target.UserFriends = source.UserFriends; + target.UserGender = source.UserGender; + target.UserGroups = source.UserGroups; + target.UserHometown = source.UserHometown; + target.UserLikes = source.UserLikes; + target.UserLink = source.UserLink; + target.UserLocation = source.UserLocation; + target.UserManagedGroups = source.UserManagedGroups; + target.UserPhotos = source.UserPhotos; + target.UserPosts = source.UserPosts; + target.UserStatus = source.UserStatus; + target.UserTaggedPlaces = source.UserTaggedPlaces; + target.UserVideos = source.UserVideos; + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalPropertiesNonOptional(up); + return target; + } + + internal static ConnectionOptionsGitHub ToApi(V2alpha1ConnectionOptionsGitHub source) + { + var target = new ConnectionOptionsGitHub(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.FreeformScopes is { } ffs) + target.FreeformScopes = ffs; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + target.AdminOrg = source.AdminOrg; + target.AdminPublicKey = source.AdminPublicKey; + target.AdminRepoHook = source.AdminRepoHook; + target.DeleteRepo = source.DeleteRepo; + target.Email = source.Email; + target.Follow = source.Follow; + target.Gist = source.Gist; + target.Notifications = source.Notifications; + target.Profile = source.Profile; + target.PublicRepo = source.PublicRepo; + target.ReadOrg = source.ReadOrg; + target.ReadPublicKey = source.ReadPublicKey; + target.ReadRepoHook = source.ReadRepoHook; + target.ReadUser = source.ReadUser; + target.Repo = source.Repo; + target.RepoDeployment = source.RepoDeployment; + target.RepoStatus = source.RepoStatus; + target.WriteOrg = source.WriteOrg; + target.WritePublicKey = source.WritePublicKey; + target.WriteRepoHook = source.WriteRepoHook; + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsGoogleApps ToApi(V2alpha1ConnectionOptionsGoogleApps source) + { + var target = new ConnectionOptionsGoogleApps { ClientId = source.ClientId, ClientSecret = source.ClientSecret }; + if (source.Scope is { } scope) + target.Scope = scope; + target.Domain = source.Domain; + if (source.DomainAliases is { } da) + target.DomainAliases = da; + target.TenantDomain = source.TenantDomain; + target.IconUrl = source.IconUrl; + target.Email = source.Email; + target.Profile = source.Profile; + target.ApiEnableUsers = source.ApiEnableUsers; + target.MapUserIdToId = source.MapUserIdToId; + target.AdminAccessToken = source.AdminAccessToken; + target.AdminAccessTokenExpiresin = source.AdminAccessTokenExpiresin; + target.AdminRefreshToken = source.AdminRefreshToken; + target.AllowSettingLoginScopes = source.AllowSettingLoginScopes; + target.ApiEnableGroups = source.ApiEnableGroups; + target.ExtAgreedTerms = source.ExtAgreedTerms; + target.ExtGroups = source.ExtGroups; + target.ExtGroupsExtended = source.ExtGroupsExtended; + target.ExtIsAdmin = source.ExtIsAdmin; + target.ExtIsSuspended = source.ExtIsSuspended; + target.HandleLoginFromSocial = source.HandleLoginFromSocial; + if (source.FederatedConnectionsAccessTokens is { } fcat) + target.FederatedConnectionsAccessTokens = new ConnectionFederatedConnectionsAccessTokens { Active = fcat.Active }; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsGoogleOAuth2 ToApi(V2alpha1ConnectionOptionsGoogleOAuth2 source) + { + var target = new ConnectionOptionsGoogleOAuth2(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.FreeformScopes is { } ffs) + target.FreeformScopes = ffs; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + target.IconUrl = source.IconUrl; + if (source.AllowedAudiences is { } aa) + target.AllowedAudiences = aa; + target.AdsenseManagement = source.AdsenseManagement; + target.Analytics = source.Analytics; + target.Blogger = source.Blogger; + target.Calendar = source.Calendar; + target.CalendarAddonsExecute = source.CalendarAddonsExecute; + target.CalendarEvents = source.CalendarEvents; + target.CalendarEventsReadonly = source.CalendarEventsReadonly; + target.CalendarSettingsReadonly = source.CalendarSettingsReadonly; + target.ChromeWebStore = source.ChromeWebStore; + target.Contacts = source.Contacts; + target.ContactsNew = source.ContactsNew; + target.ContactsOtherReadonly = source.ContactsOtherReadonly; + target.ContactsReadonly = source.ContactsReadonly; + target.ContentApiForShopping = source.ContentApiForShopping; + target.Coordinate = source.Coordinate; + target.CoordinateReadonly = source.CoordinateReadonly; + target.DirectoryReadonly = source.DirectoryReadonly; + target.DocumentList = source.DocumentList; + target.Drive = source.Drive; + target.DriveActivity = source.DriveActivity; + target.DriveActivityReadonly = source.DriveActivityReadonly; + target.DriveAppdata = source.DriveAppdata; + target.DriveAppsReadonly = source.DriveAppsReadonly; + target.DriveFile = source.DriveFile; + target.DriveMetadata = source.DriveMetadata; + target.DriveMetadataReadonly = source.DriveMetadataReadonly; + target.DrivePhotosReadonly = source.DrivePhotosReadonly; + target.DriveReadonly = source.DriveReadonly; + target.DriveScripts = source.DriveScripts; + target.Email = source.Email; + target.Gmail = source.Gmail; + target.GmailCompose = source.GmailCompose; + target.GmailInsert = source.GmailInsert; + target.GmailLabels = source.GmailLabels; + target.GmailMetadata = source.GmailMetadata; + target.GmailModify = source.GmailModify; + target.GmailNew = source.GmailNew; + target.GmailReadonly = source.GmailReadonly; + target.GmailSend = source.GmailSend; + target.GmailSettingsBasic = source.GmailSettingsBasic; + target.GmailSettingsSharing = source.GmailSettingsSharing; + target.GoogleAffiliateNetwork = source.GoogleAffiliateNetwork; + target.GoogleBooks = source.GoogleBooks; + target.GoogleCloudStorage = source.GoogleCloudStorage; + target.GoogleDrive = source.GoogleDrive; + target.GoogleDriveFiles = source.GoogleDriveFiles; + target.GooglePlus = source.GooglePlus; + target.LatitudeBest = source.LatitudeBest; + target.LatitudeCity = source.LatitudeCity; + target.Moderator = source.Moderator; + target.OfflineAccess = source.OfflineAccess; + target.Orkut = source.Orkut; + target.PicasaWeb = source.PicasaWeb; + target.Profile = source.Profile; + target.Sites = source.Sites; + target.Tasks = source.Tasks; + target.TasksReadonly = source.TasksReadonly; + target.UrlShortener = source.UrlShortener; + target.WebmasterTools = source.WebmasterTools; + target.Youtube = source.Youtube; + target.YoutubeChannelmembershipsCreator = source.YoutubeChannelmembershipsCreator; + target.YoutubeNew = source.YoutubeNew; + target.YoutubeReadonly = source.YoutubeReadonly; + target.YoutubeUpload = source.YoutubeUpload; + target.Youtubepartner = source.Youtubepartner; + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsLinkedin ToApi(V2alpha1ConnectionOptionsLinkedin source) + { + var target = new ConnectionOptionsLinkedin(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.FreeformScopes is { } ffs) + target.FreeformScopes = ffs; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + target.BasicProfile = source.BasicProfile; + target.Email = source.Email; + target.FullProfile = source.FullProfile; + target.Network = source.Network; + target.Openid = source.Openid; + target.Profile = source.Profile; + target.StrategyVersion = source.StrategyVersion; + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsOAuth1 ToApi(V2alpha1ConnectionOptionsOAuth1 source) + { + var target = new ConnectionOptionsOAuth1(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + target.AccessTokenUrl = source.AccessTokenUrl; + target.RequestTokenUrl = source.RequestTokenUrl; + if (source.SignatureMethod is not null) + target.SignatureMethod = ToApi(source.SignatureMethod); + target.UserAuthorizationUrl = source.UserAuthorizationUrl; + if (source.Scripts is { } sc) + target.Scripts = new ConnectionScriptsOAuth1 { FetchUserProfile = sc.FetchUserProfile }; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsOAuth2 ToApi(V2alpha1ConnectionOptionsOAuth2 source) + { + var target = new ConnectionOptionsOAuth2(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + target.AuthorizationUrl = source.AuthorizationUrl; + target.TokenUrl = source.TokenUrl; + target.LogoutUrl = source.LogoutUrl; + if (source.Scope is { } scope) + target.Scope = string.Join(" ", scope); + target.IconUrl = source.IconUrl; + target.PkceEnabled = source.PkceEnabled; + target.UseOauthSpecScope = source.UseOauthSpecScope; + if (source.Scripts is { } sc) + target.Scripts = new ConnectionScriptsOAuth2 { FetchUserProfile = sc.FetchUserProfile }; + if (source.AuthParams is { } ap) + target.AuthParams = ap.ToDictionary(kv => kv.Key, kv => kv.Value); + if (source.AuthParamsMap is { } apm) + target.AuthParamsMap = apm.ToDictionary(kv => kv.Key, kv => kv.Value); + if (source.FieldsMap is { } fm) + target.FieldsMap = fm.ToDictionary(kv => kv.Key, kv => kv.Value); + if (source.CustomHeaders is { } ch) + target.CustomHeaders = ch.ToDictionary(kv => kv.Key, kv => kv.Value); + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsOffice365 ToApi(V2alpha1ConnectionOptionsOffice365 source) + { + var target = new ConnectionOptionsOffice365(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + return target; + } + + internal static ConnectionOptionsOidc ToApi(V2alpha1ConnectionOptionsOidc source) + { + var target = new ConnectionOptionsOidc { ClientId = source.ClientId, ClientSecret = source.ClientSecret }; + target.DiscoveryUrl = source.DiscoveryUrl; + target.AuthorizationEndpoint = source.AuthorizationEndpoint; + target.TokenEndpoint = source.TokenEndpoint; + target.UserinfoEndpoint = source.UserinfoEndpoint; + target.JwksUri = source.JwksUri; + target.Issuer = source.Issuer; + target.Scope = source.Scope; + target.IconUrl = source.IconUrl; + if (source.DomainAliases is { } da) + target.DomainAliases = da; + target.TenantDomain = source.TenantDomain; + if (source.TokenEndpointAuthMethod is not null) + target.TokenEndpointAuthMethod = ToApi(source.TokenEndpointAuthMethod); + if (source.TokenEndpointAuthSigningAlg is not null) + target.TokenEndpointAuthSigningAlg = ToApi(source.TokenEndpointAuthSigningAlg); + if (source.TokenEndpointJwtcaAudFormat is not null) + target.TokenEndpointJwtcaAudFormat = ToApi(source.TokenEndpointJwtcaAudFormat); + if (source.DpopSigningAlg is not null) + target.DpopSigningAlg = ToApi(source.DpopSigningAlg); + target.SendBackChannelNonce = source.SendBackChannelNonce; + if (source.Type is not null) + target.Type = ToApi(source.Type); + if (source.OidcMetadata is { } oidcMetadata) + target.OidcMetadata = ToApi(oidcMetadata); + if (source.IdTokenSignedResponseAlgs is { } algs) + target.IdTokenSignedResponseAlgs = ToApi(algs); + if (source.AttributeMap is { } am) + target.AttributeMap = ToApi(am); + if (source.ConnectionSettings is { } cs) + target.ConnectionSettings = ToApi(cs); + if (source.FederatedConnectionsAccessTokens is { } fcat) + target.FederatedConnectionsAccessTokens = ToApi(fcat); + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsOkta ToApi(V2alpha1ConnectionOptionsOkta source) + { + var target = new ConnectionOptionsOkta { ClientId = source.ClientId, ClientSecret = source.ClientSecret }; + target.Domain = source.Domain; + target.AuthorizationEndpoint = source.AuthorizationEndpoint; + target.TokenEndpoint = source.TokenEndpoint; + target.UserinfoEndpoint = source.UserinfoEndpoint; + target.JwksUri = source.JwksUri; + target.Issuer = source.Issuer; + target.Scope = source.Scope; + target.IconUrl = source.IconUrl; + if (source.DomainAliases is { } da) + target.DomainAliases = da; + target.TenantDomain = source.TenantDomain; + if (source.TokenEndpointAuthMethod is not null) + target.TokenEndpointAuthMethod = ToApi(source.TokenEndpointAuthMethod); + if (source.TokenEndpointAuthSigningAlg is not null) + target.TokenEndpointAuthSigningAlg = ToApi(source.TokenEndpointAuthSigningAlg); + if (source.TokenEndpointJwtcaAudFormat is not null) + target.TokenEndpointJwtcaAudFormat = ToApi(source.TokenEndpointJwtcaAudFormat); + if (source.DpopSigningAlg is not null) + target.DpopSigningAlg = ToApi(source.DpopSigningAlg); + target.SendBackChannelNonce = source.SendBackChannelNonce; + if (source.Type is not null) + target.Type = ToApi(source.Type); + if (source.OidcMetadata is { } oidcMetadata) + target.OidcMetadata = ToApi(oidcMetadata); + if (source.IdTokenSignedResponseAlgs is { } algs) + target.IdTokenSignedResponseAlgs = ToApi(algs); + if (source.AttributeMap is { } am) + target.AttributeMap = ToApi(am); + if (source.ConnectionSettings is { } cs) + target.ConnectionSettings = ToApi(cs); + if (source.FederatedConnectionsAccessTokens is { } fcat) + target.FederatedConnectionsAccessTokens = ToApi(fcat); + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsPaypal ToApi(V2alpha1ConnectionOptionsPaypal source) + { + var target = new ConnectionOptionsPaypal(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.FreeformScopes is { } ffs) + target.FreeformScopes = ffs; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + target.Address = source.Address; + target.Email = source.Email; + target.Phone = source.Phone; + target.Profile = source.Profile; + return target; + } + + internal static ConnectionOptionsPingFederate ToApi(V2alpha1ConnectionOptionsPingFederate source) + { + var target = new ConnectionOptionsPingFederate { PingFederateBaseUrl = source.PingFederateBaseUrl }; + target.SignInEndpoint = source.SignInEndpoint; + target.EntityId = source.EntityId; + target.Cert = source.Cert; + target.SigningCert = source.SigningCert; + if (source.DecryptionKey is { } decryptionKey) + target.DecryptionKey = ToApi(decryptionKey); + if (source.Thumbprints is { } tp) + target.Thumbprints = tp; + if (source.SignatureAlgorithm is { } sigAlg) + target.SignatureAlgorithm = ToApi(sigAlg); + if (source.DigestAlgorithm is { } digAlg) + target.DigestAlgorithm = ToApi(digAlg); + if (source.ProtocolBinding is { } pb) + target.ProtocolBinding = ToApi(pb); + target.SignSamlRequest = source.SignSamlRequest; + if (source.Idpinitiated is { } idp) + target.Idpinitiated = ToApi(idp); + if (source.AssertionDecryptionSettings is { } ads) + target.AssertionDecryptionSettings = ToApi(ads); + target.IconUrl = source.IconUrl; + if (source.DomainAliases is { } da) + target.DomainAliases = da; + target.TenantDomain = source.TenantDomain; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsSalesforce ToApi(V2alpha1ConnectionOptionsSalesforce source) + { + var target = new ConnectionOptionsSalesforce(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.FreeformScopes is { } ffs) + target.FreeformScopes = ffs; + target.Profile = source.Profile; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsSalesforceCommunity ToApi(V2alpha1ConnectionOptionsSalesforceCommunity source) + { + var target = new ConnectionOptionsSalesforceCommunity(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + target.CommunityBaseUrl = source.CommunityBaseUrl; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.FreeformScopes is { } ffs) + target.FreeformScopes = ffs; + target.Profile = source.Profile; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsSaml ToApi(V2alpha1ConnectionOptionsSaml source) + { + var target = new ConnectionOptionsSaml(); + target.SignInEndpoint = source.SignInEndpoint; + target.SignOutEndpoint = source.SignOutEndpoint; + target.DisableSignout = source.DisableSignout; + target.DestinationUrl = source.DestinationUrl; + target.RecipientUrl = source.RecipientUrl; + target.Cert = source.Cert; + if (source.Thumbprints is { } tp) + target.Thumbprints = tp; + target.MetadataUrl = source.MetadataUrl; + target.MetadataXml = source.MetadataXml; + target.EntityId = source.EntityId; + target.SignSamlRequest = source.SignSamlRequest; + if (source.SignatureAlgorithm is { } sigAlg) + target.SignatureAlgorithm = ToApi(sigAlg); + if (source.DigestAlgorithm is { } digAlg) + target.DigestAlgorithm = ToApi(digAlg); + if (source.ProtocolBinding is { } pb) + target.ProtocolBinding = ToApi(pb); + target.RequestTemplate = source.RequestTemplate; + target.Debug = source.Debug; + target.Deflate = source.Deflate; + if (source.Idpinitiated is { } idp) + target.Idpinitiated = ToApi(idp); + target.SigningCert = source.SigningCert; + if (source.SigningKey is { } sk) + target.SigningKey = ToApi(sk); + if (source.DecryptionKey is { } decryptionKey) + target.DecryptionKey = ToApi(decryptionKey); + if (source.AssertionDecryptionSettings is { } ads) + target.AssertionDecryptionSettings = ToApi(ads); + target.UserIdAttribute = source.UserIdAttribute; + target.IconUrl = source.IconUrl; + if (source.DomainAliases is { } da) + target.DomainAliases = da; + target.TenantDomain = source.TenantDomain; + target.GlobalTokenRevocationJwtIss = source.GlobalTokenRevocationJwtIss; + target.GlobalTokenRevocationJwtSub = source.GlobalTokenRevocationJwtSub; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsSms ToApi(V2alpha1ConnectionOptionsSms source) + { + var target = new ConnectionOptionsSms(); + target.Name = source.Name; + target.From = source.From; + target.Template = source.Template; + target.TwilioSid = source.TwilioSid; + target.TwilioToken = source.TwilioToken; + target.MessagingServiceSid = source.MessagingServiceSid; + target.GatewayUrl = source.GatewayUrl; + target.ForwardReqInfo = source.ForwardReqInfo; + target.DisableSignup = source.DisableSignup; + target.BruteForceProtection = source.BruteForceProtection; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.Totp is { } t) + target.Totp = new ConnectionTotpSms { Length = t.Length, TimeStep = t.TimeStep }; + if (source.GatewayAuthentication is { } ga) + target.GatewayAuthentication = ToApi(ga); + return target; + } + + internal static ConnectionOptionsTwitter ToApi(V2alpha1ConnectionOptionsTwitter source) + { + var target = new ConnectionOptionsTwitter(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.FreeformScopes is { } ffs) + target.FreeformScopes = ffs; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.Protocol is not null) + target.Protocol = ToApi(source.Protocol); + target.OfflineAccess = source.OfflineAccess; + target.Profile = source.Profile; + target.TweetRead = source.TweetRead; + target.UsersRead = source.UsersRead; + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsWindowsLive ToApi(V2alpha1ConnectionOptionsWindowsLive source) + { + var target = new ConnectionOptionsWindowsLive(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.Scope is { } scope) + target.Scope = scope; + if (source.FreeformScopes is { } ffs) + target.FreeformScopes = ffs; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + target.Basic = source.Basic; + target.OfflineAccess = source.OfflineAccess; + target.Signin = source.Signin; + target.Birthday = source.Birthday; + target.Calendars = source.Calendars; + target.CalendarsUpdate = source.CalendarsUpdate; + target.ContactsBirthday = source.ContactsBirthday; + target.ContactsCreate = source.ContactsCreate; + target.ContactsCalendars = source.ContactsCalendars; + target.ContactsPhotos = source.ContactsPhotos; + target.ContactsSkydrive = source.ContactsSkydrive; + target.Emails = source.Emails; + target.EventsCreate = source.EventsCreate; + target.Messenger = source.Messenger; + target.PhoneNumbers = source.PhoneNumbers; + target.Photos = source.Photos; + target.PostalAddresses = source.PostalAddresses; + target.Share = source.Share; + target.Skydrive = source.Skydrive; + target.SkydriveUpdate = source.SkydriveUpdate; + target.WorkProfile = source.WorkProfile; + target.Applications = source.Applications; + target.ApplicationsCreate = source.ApplicationsCreate; + target.StrategyVersion = source.StrategyVersion; + target.DirectoryAccessasuserAll = source.DirectoryAccessasuserAll; + target.DirectoryReadAll = source.DirectoryReadAll; + target.DirectoryReadwriteAll = source.DirectoryReadwriteAll; + target.GraphCalendars = source.GraphCalendars; + target.GraphCalendarsUpdate = source.GraphCalendarsUpdate; + target.GraphContacts = source.GraphContacts; + target.GraphContactsUpdate = source.GraphContactsUpdate; + target.GraphDevice = source.GraphDevice; + target.GraphDeviceCommand = source.GraphDeviceCommand; + target.GraphEmails = source.GraphEmails; + target.GraphEmailsUpdate = source.GraphEmailsUpdate; + target.GraphFiles = source.GraphFiles; + target.GraphFilesAll = source.GraphFilesAll; + target.GraphFilesAllUpdate = source.GraphFilesAllUpdate; + target.GraphFilesUpdate = source.GraphFilesUpdate; + target.GraphNotes = source.GraphNotes; + target.GraphNotesCreate = source.GraphNotesCreate; + target.GraphNotesUpdate = source.GraphNotesUpdate; + target.GraphTasks = source.GraphTasks; + target.GraphTasksUpdate = source.GraphTasksUpdate; + target.GraphUser = source.GraphUser; + target.GraphUserActivity = source.GraphUserActivity; + target.GraphUserUpdate = source.GraphUserUpdate; + target.GroupReadAll = source.GroupReadAll; + target.GroupReadwriteAll = source.GroupReadwriteAll; + target.MailReadwriteAll = source.MailReadwriteAll; + target.MailSend = source.MailSend; + target.RolemanagementReadAll = source.RolemanagementReadAll; + target.RolemanagementReadwriteDirectory = source.RolemanagementReadwriteDirectory; + target.SitesReadAll = source.SitesReadAll; + target.SitesReadwriteAll = source.SitesReadwriteAll; + target.TeamReadbasicAll = source.TeamReadbasicAll; + target.TeamReadwriteAll = source.TeamReadwriteAll; + target.UserReadAll = source.UserReadAll; + target.UserReadbasicAll = source.UserReadbasicAll; + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + internal static ConnectionOptionsYahoo ToApi(V2alpha1ConnectionOptionsYahoo source) + { + var target = new ConnectionOptionsYahoo(); + target.ClientId = source.ClientId; + target.ClientSecret = source.ClientSecret; + if (source.NonPersistentAttrs is { } npa) + target.NonPersistentAttrs = npa; + if (source.SetUserRootAttributes is not null) + target.SetUserRootAttributes = ToApi(source.SetUserRootAttributes); + if (source.UpstreamParams is { } up) + target.UpstreamParams = ToApiUpstreamAdditionalProperties(up); + return target; + } + + /// + /// Gets the list of enabled client IDs + /// + /// + /// + /// + /// + async Task GetEnabledClientsAsync(IManagementApiClient api, string connectionId, CancellationToken cancellationToken) + { + var pager = await api.Connections.Clients.GetAsync(connectionId, new GetConnectionEnabledClientsRequestParameters(), null, cancellationToken); + + var l = new List(); + foreach (var client in pager.CurrentPage.Items) + if (client.ClientId is not null) + l.Add(client.ClientId); + + return l.ToArray(); + } + + /// + protected override async Task Get(IManagementApiClient api, string id, string defaultNamespace, CancellationToken cancellationToken) + { + try + { + var self = await api.Connections.GetAsync(id, new GetConnectionRequestParameters(), null, cancellationToken); + if (self == null) + return null; + + var conf = FromApi(self); + conf.EnabledClients = (await GetEnabledClientsAsync(api, id, cancellationToken)).Select(i => new V1ClientReference() { Id = i }).ToArray(); + return conf; + } + catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) + { + return null; + } + } + + /// + protected override async Task Find(IManagementApiClient api, V2alpha1Connection entity, V2alpha1Connection.SpecDef spec, string defaultNamespace, CancellationToken cancellationToken) + { + if (spec.Find is not null) + { + if (spec.Find.ConnectionId is string connectionId) + { + try + { + var connection = await api.Connections.GetAsync(connectionId, new GetConnectionRequestParameters(), null, cancellationToken); + Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} found existing connection: {Name}", EntityTypeName, entity.Namespace(), entity.Name(), connection.Name); + return connection.Id; + } + catch (ErrorApiException e) when (e.StatusCode == HttpStatusCode.NotFound) + { + Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} could not find connection with id {ConnectionId}.", EntityTypeName, entity.Namespace(), entity.Name(), connectionId); + return null; + } + } + + return null; + } + else + { + var conf = spec.Init ?? spec.Conf; + if (conf is null || string.IsNullOrEmpty(conf.Name)) + return null; + + var pager = await api.Connections.ListAsync(new ListConnectionsQueryParameters { Name = conf.Name }, null, cancellationToken); + var self = pager.CurrentPage.Items?.FirstOrDefault(i => i.Name == conf.Name); + if (self is not null) + Logger.LogInformation("{EntityTypeName} {EntityNamespace}/{EntityName} found existing connection by name: {Name}", EntityTypeName, entity.Namespace(), entity.Name(), conf.Name); + + return self?.Id; + } + } + + /// + protected override string? ValidateCreate(V2alpha1ConnectionConf conf) + { + return null; + } + + /// + /// Attempts to resolve the list of client references to client IDs. + /// + /// + /// + /// + /// + /// + /// + async Task ResolveClientRefsToIds(IManagementApiClient api, V1ClientReference[]? refs, string defaultNamespace, CancellationToken cancellationToken) + { + if (refs is null) + return Array.Empty(); + + var l = new List(refs.Length); + + foreach (var i in refs) + l.Add(await ResolveClientRefToId(api, i, defaultNamespace, cancellationToken) ?? throw new InvalidOperationException()); + + return l.ToArray(); + } + + /// + protected override async Task Create(IManagementApiClient api, V2alpha1ConnectionConf conf, string defaultNamespace, CancellationToken cancellationToken) + { + Logger.LogInformation("{EntityTypeName} creating connection in Auth0 with name: {ConnectionName} and strategy: {Strategy}", EntityTypeName, conf.Name, conf.Strategy); + + if (conf.Strategy is null) + throw new InvalidOperationException("Missing connection strategy."); + + var req = new CreateConnectionRequestContent() + { + Name = conf.Name ?? throw new InvalidOperationException("Missing connection name."), + Strategy = ConnectionIdentityProviderEnum.FromCustom(JsonSerializer.Serialize(conf.Strategy).Trim('"')), + }; + + ApplyToApi(conf, req); + + var self = await api.Connections.CreateAsync(req, null, cancellationToken); + if (self is null) + throw new InvalidOperationException(); + + Logger.LogInformation("{EntityTypeName} successfully created connection in Auth0 with ID: {ConnectionId}, name: {ConnectionName} and strategy: {Strategy}", EntityTypeName, self.Id, conf.Name, conf.Strategy); + return self.Id; + } + + /// + protected override async Task Update(IManagementApiClient api, string id, V2alpha1ConnectionConf? last, V2alpha1ConnectionConf conf, string defaultNamespace, CancellationToken cancellationToken) + { + Logger.LogInformation("{EntityTypeName} updating connection in Auth0 with ID: {ConnectionId}, name: {ConnectionName} and strategy: {Strategy}", EntityTypeName, id, conf.Name, conf.Strategy); + + var req = new UpdateConnectionRequestContent(); + ApplyToApi(conf, req); + + await api.Connections.UpdateAsync(id, req, null, cancellationToken); + await UpdateEnabledClientsAsync(api, id, conf, defaultNamespace, cancellationToken); + + Logger.LogInformation("{EntityTypeName} successfully updated connection in Auth0 with ID: {ConnectionId}, name: {ConnectionName} and strategy: {Strategy}", EntityTypeName, id, conf.Name, conf.Strategy); + } + + /// + /// Resolves the strategy-specific options object for the given strategy name and options. + /// + /// + /// + /// + internal static object? ResolveStrategyOptions(V2alpha1ConnectionStrategy? strategy, V2alpha1ConnectionOptions? options) => strategy switch + { + V2alpha1ConnectionStrategy.Auth0 when options?.Auth0 is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Ad when options?.Ad is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Adfs when options?.Adfs is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Auth0Oidc when options?.Auth0Oidc is { } o => ToApi(o), + V2alpha1ConnectionStrategy.AzureAd when options?.AzureAd is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Bitbucket when options?.Bitbucket is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Box when options?.Box is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Dropbox when options?.Dropbox is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Email when options?.Email is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Evernote when options?.Evernote is { } o => ToApi(o), + V2alpha1ConnectionStrategy.EvernoteSandbox when options?.EvernoteSandbox is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Exact when options?.Exact is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Facebook when options?.Facebook is { } o => ToApi(o), + V2alpha1ConnectionStrategy.GitHub when options?.GitHub is { } o => ToApi(o), + V2alpha1ConnectionStrategy.GoogleApps when options?.GoogleApps is { } o => ToApi(o), + V2alpha1ConnectionStrategy.GoogleOAuth2 when options?.GoogleOAuth2 is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Linkedin when options?.Linkedin is { } o => ToApi(o), + V2alpha1ConnectionStrategy.OAuth1 when options?.OAuth1 is { } o => ToApi(o), + V2alpha1ConnectionStrategy.OAuth2 when options?.OAuth2 is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Office365 when options?.Office365 is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Oidc when options?.Oidc is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Okta when options?.Okta is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Paypal when options?.Paypal is { } o => ToApi(o), + V2alpha1ConnectionStrategy.PaypalSandbox when options?.PaypalSandbox is { } o => ToApi(o), + V2alpha1ConnectionStrategy.PingFederate when options?.PingFederate is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Salesforce when options?.Salesforce is { } o => ToApi(o), + V2alpha1ConnectionStrategy.SalesforceCommunity when options?.SalesforceCommunity is { } o => ToApi(o), + V2alpha1ConnectionStrategy.SalesforceSandbox when options?.SalesforceSandbox is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Saml when options?.Saml is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Sms when options?.Sms is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Twitter when options?.Twitter is { } o => ToApi(o), + V2alpha1ConnectionStrategy.WindowsLive when options?.WindowsLive is { } o => ToApi(o), + V2alpha1ConnectionStrategy.Yahoo when options?.Yahoo is { } o => ToApi(o), + _ => null, + }; + + /// + /// Applies the specified configuration to the request object. + /// + /// + /// + internal static void ApplyToApi(V2alpha1ConnectionConf source, CreateConnectionRequestContent target) + { + if (source.Name is { } name) + target.Name = name; + + if (source.DisplayName is { } displayName) + target.DisplayName = displayName; + + if (source.Metadata is { } metadata) + target.Metadata = metadata.Cast().ToDictionary(e => (string)e.Key, e => e.Value?.ToString()); + + if (source.Realms is { } realms) + target.Realms = realms; + + if (source.IsDomainConnection is not null) + target.IsDomainConnection = source.IsDomainConnection ?? false; + + if (source.ShowAsButton is { } showAsButton) + target.ShowAsButton = showAsButton; + + var options = ResolveStrategyOptions(source.Strategy, source.Options); + if (options is not null) + target.Options = JsonSerializer.Deserialize(JsonSerializer.Serialize(options)); + } + + internal static void ApplyToApi(V2alpha1ConnectionConf source, UpdateConnectionRequestContent target) + { + if (source.DisplayName is { } displayName) + target.DisplayName = displayName; + + if (source.Metadata is { } metadata) + target.Metadata = metadata.Cast().ToDictionary(e => (string)e.Key, e => e.Value?.ToString()); + + if (source.Realms is { } realms) + target.Realms = realms; + + if (source.IsDomainConnection is not null) + target.IsDomainConnection = source.IsDomainConnection ?? false; + + if (source.ShowAsButton is { } showAsButton) + target.ShowAsButton = showAsButton; + + var options = ResolveStrategyOptions(source.Strategy, source.Options); + if (options is not null) + target.Options = JsonSerializer.Deserialize(JsonSerializer.Serialize(options)); + } + + static void ApplyToApi(V2alpha1ConnectionOptionsEmailAttribute source, EmailAttribute target) + { + if (source.Identifier is { } identifier) + { + target.Identifier ??= new ConnectionAttributeIdentifier(); + ApplyToApi(identifier, target.Identifier); + } + + if (source.ProfileRequired is { } profileRequired) + target.ProfileRequired = profileRequired; + + if (source.Signup is { } signup) + { + target.Signup ??= new SignupVerified(); + ApplyToApi(signup, target.Signup); + } + } + + static void ApplyToApi(V2alpha1ConnectionOptionsEmailSignup source, SignupVerified target) + { + if (source.Status is { } status) + target.Status = ToApi(status); + + if (source.Verification is { } verification) + { + target.Verification ??= new SignupVerification(); + ApplyToApi(verification, target.Verification); + } + } + + static void ApplyToApi(V2alpha1ConnectionOptionsPhoneNumberAttribute source, PhoneAttribute target) + { + if (source.Signup is { } signup) + { + target.Signup ??= new SignupVerified(); + ApplyToApi(signup, target.Signup, true); + } + } + + static void ApplyToApi(V2alpha1ConnectionOptionsPhoneNumberSignup source, SignupVerified target, bool phone) + { + if (source.Status is { } status) + target.Status = ToApi(status); + + if (source.Verification is { } verification) + { + target.Verification ??= new SignupVerification(); + ApplyToApi(verification, target.Verification); + } + } + + static void ApplyToApi(V2alpha1ConnectionOptionsUsernameAttribute source, UsernameAttribute target) + { + if (source.Identifier is { } identifier) + { + target.Identifier ??= new ConnectionAttributeIdentifier(); + ApplyToApi(identifier, target.Identifier); + } + + if (source.ProfileRequired is { } profileRequired) + target.ProfileRequired = profileRequired; + + if (source.Signup is { } signup) + { + target.Signup ??= new SignupSchema(); + ApplyToApi(signup, target.Signup); + } + + if (source.Validation is { } validation) + { + target.Validation ??= new UsernameValidation(); + ApplyToApi(validation, target.Validation); + } + } + + static void ApplyToApi(V2alpha1ConnectionOptionsUsernameSignup source, SignupSchema target) + { + if (source.Status is { } status) + target.Status = ToApi(status); + } + + static void ApplyToApi(V2alpha1ConnectionOptionsAttributeIdentifier source, ConnectionAttributeIdentifier target) + { + if (source.Active is { } active) + target.Active = active; + } + + static void ApplyToApi(V2alpha1ConnectionOptionsAttributeValidation source, UsernameValidation target) + { + if (source.MinLength is { } minLength) + target.MinLength = minLength; + + if (source.MaxLength is { } maxLength) + target.MaxLength = maxLength; + + if (source.AllowedTypes is { } allowedTypes) + { + target.AllowedTypes ??= new UsernameAllowedTypes(); + ApplyToApi(allowedTypes, target.AllowedTypes); + } + } + + static void ApplyToApi(V2alpha1ConnectionOptionsAttributeAllowedTypes source, UsernameAllowedTypes target) + { + if (source.Email is { } email) + target.Email = email; + + if (source.PhoneNumber is { } phoneNumber) + target.PhoneNumber = phoneNumber; + } + + static void ApplyToApi(V2alpha1ConnectionOptionsVerification source, SignupVerification target) + { + if (source.Active is { } active) + target.Active = active; + } + + static void ApplyToApi(V2alpha1ConnectionCustomScripts source, ConnectionCustomScripts target) + { + if (source.Login is { } login) + target.Login = login; + + if (source.GetUser is { } getUser) + target.GetUser = getUser; + + if (source.Delete is { } delete) + target.Delete = delete; + + if (source.ChangePassword is { } changePassword) + target.ChangePassword = changePassword; + + if (source.Verify is { } verify) + target.Verify = verify; + + if (source.Create is { } create) + target.Create = create; + + if (source.ChangeUsername is { } changeUsername) + target.ChangeUsername = changeUsername; + + if (source.ChangeEmail is { } changeEmail) + target.ChangeEmail = changeEmail; + + if (source.ChangePhoneNumber is { } changePhoneNumber) + target.ChangePhoneNumber = changePhoneNumber; + } + + static void ApplyToApi(V2alpha1ConnectionOptionsCustomScripts source, ConnectionCustomScripts target) + { + if (source.Login is { } login) + target.Login = login; + + if (source.GetUser is { } getUser) + target.GetUser = getUser; + + if (source.Delete is { } delete) + target.Delete = delete; + + if (source.ChangePassword is { } changePassword) + target.ChangePassword = changePassword; + + if (source.Verify is { } verify) + target.Verify = verify; + + if (source.Create is { } create) + target.Create = create; + + if (source.ChangeUsername is { } changeUsername) + target.ChangeUsername = changeUsername; + + if (source.ChangeEmail is { } changeEmail) + target.ChangeEmail = changeEmail; + + if (source.ChangePhoneNumber is { } changePhoneNumber) + target.ChangePhoneNumber = changePhoneNumber; + } + + static void ApplyToApi(V2alpha1ConnectionOptionsAuthenticationMethods source, ConnectionAuthenticationMethods target) + { + if (source.Password is { } password) + { + target.Password ??= new ConnectionPasswordAuthenticationMethod(); + ApplyToApi(password, target.Password); + } + + if (source.Passkey is { } passkey) + { + target.Passkey ??= new ConnectionPasskeyAuthenticationMethod(); + ApplyToApi(passkey, target.Passkey); + } + } + + static void ApplyToApi(V2alpha1ConnectionOptionsPasswordAuthenticationMethod source, ConnectionPasswordAuthenticationMethod target) + { + if (source.Enabled is { } enabled) + target.Enabled = enabled; + } + + static void ApplyToApi(V2alpha1ConnectionOptionsPasskeyAuthenticationMethod source, ConnectionPasskeyAuthenticationMethod target) + { + if (source.Enabled is { } enabled) + target.Enabled = enabled; + } + + static void ApplyToApi(V2alpha1ConnectionOptionsPasskeyOptions source, ConnectionPasskeyOptions target) + { + if (source.ChallengeUi is { } challengeUi) + target.ChallengeUi = ToApi(challengeUi); + + if (source.ProgressiveEnrollmentEnabled is { } progressiveEnrollmentEnabled) + target.ProgressiveEnrollmentEnabled = progressiveEnrollmentEnabled; + + if (source.LocalEnrollmentEnabled is { } localEnrollmentEnabled) + target.LocalEnrollmentEnabled = localEnrollmentEnabled; + } + + static void ApplyToApi(V2alpha1ConnectionOptionsPasswordComplexityOptions source, ConnectionPasswordComplexityOptions target) + { + if (source.MinLength is { } minLength) + target.MinLength = minLength; + } + + static void ApplyToApi(V2alpha1ConnectionOptionsPasswordHistory source, ConnectionPasswordHistoryOptions target) + { + if (source.Enable is { } enable) + target.Enable = enable; + + if (source.Size is { } size) + target.Size = size; + } + + static void ApplyToApi(V2alpha1ConnectionOptionsPasswordNoPersonalInfo source, ConnectionPasswordNoPersonalInfoOptions target) + { + if (source.Enable is { } enable) + target.Enable = enable; + } + + static void ApplyToApi(V2alpha1ConnectionOptionsPasswordDictionary source, ConnectionPasswordDictionaryOptions target) + { + if (source.Enable is { } enable) + target.Enable = enable; + + if (source.Dictionary is { } dictionary) + target.Dictionary = dictionary; + } + + static void ApplyToApi(V2alpha1ConnectionGatewayAuthentication source, ConnectionGatewayAuthentication target) + { + if (source.Method is { } method) + target.Method = method; + + if (source.Subject is { } subject) + target.Subject = subject; + + if (source.Audience is { } audience) + target.Audience = audience; + + if (source.Secret is { } secret) + target.Secret = secret; + + if (source.SecretBase64Encoded is { } secretBase64Encoded) + target.SecretBase64Encoded = secretBase64Encoded; + } + + static void ApplyToApi(V2alpha1ConnectionOptions source, ref dynamic target) + { + var json = System.Text.Json.JsonSerializer.Serialize(source); + var patch = JObject.Parse(json); + + if (target is not JObject targetObj) + targetObj = new JObject(); + + MergeJObject(patch, targetObj); + target = targetObj; + } + + static void MergeJObject(JObject source, JObject target) + { + foreach (var property in source.Properties()) + { + if (target[property.Name] is JObject existingObj && property.Value is JObject sourceObj) + MergeJObject(sourceObj, existingObj); + else + target[property.Name] = property.Value; + } + } + + /// + /// Applies the update of enabled clients. + /// + /// + /// + /// + /// + /// + /// + async Task UpdateEnabledClientsAsync(IManagementApiClient api, string id, V2alpha1ConnectionConf conf, string defaultNamespace, CancellationToken cancellationToken) + { + if (conf.EnabledClients is not null) + { + var req = new List(); + + // apply existing clients, disabled by default + var existingResponse = await api.Connections.Clients.GetAsync(id, new GetConnectionEnabledClientsRequestParameters(), null, cancellationToken); + if (existingResponse?.CurrentPage?.Items is { } existingItems) + foreach (var current in existingItems) + if (current.ClientId is not null) + req.Add(new UpdateEnabledClientConnectionsRequestContentItem() { ClientId = current.ClientId, Status = false }); + + // add or enable clients specified in the configuration + foreach (var clientId in await ResolveClientRefsToIds(api, conf.EnabledClients, defaultNamespace, cancellationToken)) + { + var existing = req.FirstOrDefault(i => i.ClientId == clientId); + if (existing is null) + req.Add(existing = new UpdateEnabledClientConnectionsRequestContentItem() { ClientId = clientId, Status = false }); + + existing.Status = true; + } + + // apply update + if (req.Count > 0) + await api.Connections.Clients.UpdateAsync(id, req, null, cancellationToken); + } + } + + /// + protected override async Task DeletedAsync(IManagementApiClient api, string id, CancellationToken cancellationToken) + { + Logger.LogInformation("{EntityTypeName} deleting connection from Auth0 with ID: {ConnectionId} (reason: Kubernetes entity deleted)", EntityTypeName, id); + await api.Connections.DeleteAsync(id, null, cancellationToken); + Logger.LogInformation("{EntityTypeName} successfully deleted connection from Auth0 with ID: {ConnectionId}", EntityTypeName, id); + } + + } + +} diff --git a/src/Alethic.Auth0.Operator/Controllers/V2alpha1TenantController.cs b/src/Alethic.Auth0.Operator/Controllers/V2alpha1TenantController.cs index 0d4f698..9b70679 100644 --- a/src/Alethic.Auth0.Operator/Controllers/V2alpha1TenantController.cs +++ b/src/Alethic.Auth0.Operator/Controllers/V2alpha1TenantController.cs @@ -8,8 +8,8 @@ using Alethic.Auth0.Operator.Models; using Alethic.Auth0.Operator.Options; -using Auth0.ManagementApi.Models; -using Auth0.ManagementApi.Models.Prompts; +using Auth0.ManagementApi; +using Auth0.ManagementApi.Tenants; using k8s.Models; @@ -38,27 +38,30 @@ public class V2alpha1TenantController : /// The Auth0 API prompt configuration to convert. /// A new instance mapped from the specified API model. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantPrompts? FromApi(Prompt? source) => source is null ? null : new() + internal static V2alpha1TenantPrompts? FromApi(GetSettingsResponseContent? source) => source is null ? null : new() { IdentifierFirst = source.IdentifierFirst, UniversalLoginExperience = FromApi(source.UniversalLoginExperience), - WebauthnPlatformFirstFactor = source.WebAuthnPlatformFirstFactor, + WebauthnPlatformFirstFactor = source.WebauthnPlatformFirstFactor, }; /// - /// Converts a universal login experience string to the corresponding enum value. + /// Converts a universal login experience enum to the corresponding enum value. /// - /// The Auth0 API universal login experience string (e.g. "new" or "classic"). - /// The matching value. - /// Thrown when the value is not a recognized experience string. + /// The Auth0 API universal login experience enum value. + /// The matching value. + /// Thrown when the value is not a recognized experience. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantUniversalLoginExperience? FromApi(string? source) => source switch + internal static V2alpha1TenantUniversalLoginExperience? FromApi(UniversalLoginExperienceEnum? source) { - "new" => V2alpha1TenantUniversalLoginExperience.New, - "classic" => V2alpha1TenantUniversalLoginExperience.Classic, - null => null, - _ => throw new NotImplementedException(), - }; + return source?.Value switch + { + UniversalLoginExperienceEnum.Values.New => V2alpha1TenantUniversalLoginExperience.New, + UniversalLoginExperienceEnum.Values.Classic => V2alpha1TenantUniversalLoginExperience.Classic, + null => null, + _ => throw new NotImplementedException(), + }; + } /// /// Converts an Auth0 API object to an internal model, including nested colors. @@ -66,9 +69,9 @@ public class V2alpha1TenantController : /// The Auth0 API branding configuration to convert. /// A new instance mapped from the specified API model. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantBranding? FromApi(Branding? source) => source is null ? null : new() + internal static V2alpha1TenantBranding? FromApi(GetBrandingResponseContent? source) => source is null ? null : new() { - LogoUrl = source.LogoUrl, + LogoUrl = source.LogoUrl, FaviconUrl = source.FaviconUrl, Colors = FromApi(source.Colors), }; @@ -82,7 +85,7 @@ public class V2alpha1TenantController : internal static V2alpha1TenantBrandingColors? FromApi(BrandingColors? source) => source is null ? null : new() { Primary = source.Primary, - PageBackground = source.PageBackground, + PageBackground = source.PageBackground?.Value?.ToString(), }; /// @@ -92,30 +95,30 @@ public class V2alpha1TenantController : /// The Auth0 API tenant settings to convert. /// A new instance mapped from the specified API model. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantSettings? FromApi(TenantSettings? source) => source is null ? null : new() + internal static V2alpha1TenantSettings? FromApi(GetTenantSettingsResponseContent? source) => source is null ? null : new() { FriendlyName = source.FriendlyName, Flags = FromApi(source.Flags), - AcrValuesSupported = source.AcrValuesSupported, - AllowedLogoutUrls = source.AllowedLogoutUrls, - ChangePassword = FromApi(source.ChangePassword), - CustomizeMfaInPostLoginAction = source.CustomizeMfaInPostLoginAction, + AcrValuesSupported = source.AcrValuesSupported.IsDefined ? source.AcrValuesSupported.Value?.ToArray() : null, + AllowedLogoutUrls = source.AllowedLogoutUrls?.ToArray(), + ChangePassword = source.ChangePassword.IsDefined ? FromApi(source.ChangePassword.Value) : null, + CustomizeMfaInPostLoginAction = source.CustomizeMfaInPostloginAction, DefaultAudience = source.DefaultAudience, DefaultDirectory = source.DefaultDirectory, - DeviceFlow = FromApi(source.DeviceFlow), - EnabledLocales = source.EnabledLocales.ToList(), - ErrorPage = FromApi(source.ErrorPage), - GuardianMfaPage = FromApi(source.GuardianMfaPage), + DeviceFlow = source.DeviceFlow.IsDefined ? FromApi(source.DeviceFlow.Value) : null, + EnabledLocales = source.EnabledLocales?.Select(i => i.Value).ToList(), + ErrorPage = source.ErrorPage.IsDefined ? FromApi(source.ErrorPage.Value) : null, + GuardianMfaPage = source.GuardianMfaPage.IsDefined ? FromApi(source.GuardianMfaPage.Value) : null, IdleSessionLifetime = source.IdleSessionLifetime, PictureUrl = source.PictureUrl, SessionLifetime = source.SessionLifetime, - SessionCookie = FromApi(source.SessionCookie), + SessionCookie = source.SessionCookie.IsDefined ? FromApi(source.SessionCookie.Value) : null, SupportEmail = source.SupportEmail, SupportUrl = source.SupportUrl, SandboxVersion = source.SandboxVersion, - SandboxVersionsAvailable = source.SandboxVersionsAvailable, + SandboxVersionsAvailable = source.SandboxVersionsAvailable?.ToArray(), PushedAuthorizationRequestsSupported = source.PushedAuthorizationRequestsSupported, - Mtls = FromApi(source.Mtls), + Mtls = source.Mtls.IsDefined ? FromApi(source.Mtls.Value) : null, }; /// @@ -124,7 +127,7 @@ public class V2alpha1TenantController : /// The Auth0 Management API TenantMtls object to convert. /// A new TenantMtls instance populated with values from the specified API model. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantMtls? FromApi(TenantMtls? source) => source is null ? null : new() + internal static V2alpha1TenantMtls? FromApi(TenantSettingsMtls? source) => source is null ? null : new() { EnableEndpointAliases = source.EnableEndpointAliases, }; @@ -135,9 +138,9 @@ public class V2alpha1TenantController : /// The Auth0 Management API session cookie to convert. /// A SessionCookie instance populated with values from the specified API model. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantSessionCookie? FromApi(SessionCookie? source) => source is null ? null: new() + internal static V2alpha1TenantSessionCookie? FromApi(SessionCookieSchema? source) => source is null ? null : new() { - Mode = source.Mode, + Mode = source.Mode.Value, }; /// @@ -146,7 +149,7 @@ public class V2alpha1TenantController : /// The Auth0 API Guardian MFA page configuration to convert. /// A new instance mapped from the specified API model. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantGuardianMfaPage? FromApi(TenantGuardianMfaPage? source) => source is null ? null : new() + internal static V2alpha1TenantGuardianMfaPage? FromApi(TenantSettingsGuardianPage? source) => source is null ? null : new() { Html = source.Html, Enabled = source.Enabled, @@ -158,7 +161,7 @@ public class V2alpha1TenantController : /// The Auth0 API error page configuration to convert. /// A new instance mapped from the specified API model. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantErrorPage? FromApi(TenantErrorPage? source) => source is null ? null : new() + internal static V2alpha1TenantErrorPage? FromApi(TenantSettingsErrorPage? source) => source is null ? null : new() { ShowLogLink = source.ShowLogLink, Url = source.Url, @@ -171,7 +174,7 @@ public class V2alpha1TenantController : /// The Auth0 API device flow configuration to convert. /// A new instance mapped from the specified API model. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantDeviceFlow? FromApi(TenantDeviceFlow? source) => source is null ? null : new() + internal static V2alpha1TenantDeviceFlow? FromApi(TenantSettingsDeviceFlow? source) => source is null ? null : new() { Charset = FromApi(source.Charset), Mask = source.Mask, @@ -184,13 +187,16 @@ public class V2alpha1TenantController : /// The matching value. /// Thrown when the charset value is not recognized. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantCharset? FromApi(TenantDeviceFlowCharset? source) => source switch + internal static V2alpha1TenantCharset? FromApi(TenantSettingsDeviceFlowCharset? source) { - TenantDeviceFlowCharset.Base20 => V2alpha1TenantCharset.Base20, - TenantDeviceFlowCharset.Digits => V2alpha1TenantCharset.Digits, - null => null, - _ => throw new NotImplementedException(), - }; + return source?.Value switch + { + TenantSettingsDeviceFlowCharset.Values.Base20 => V2alpha1TenantCharset.Base20, + TenantSettingsDeviceFlowCharset.Values.Digits => V2alpha1TenantCharset.Digits, + null => null, + _ => throw new NotImplementedException(), + }; + } /// /// Converts an Auth0 API TenantChangePassword to an internal model. @@ -198,7 +204,7 @@ public class V2alpha1TenantController : /// The Auth0 API change password page configuration to convert. /// A new instance mapped from the specified API model. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantChangePassword? FromApi(TenantChangePassword? source) => source is null ? null : new() + internal static V2alpha1TenantChangePassword? FromApi(TenantSettingsPasswordPage? source) => source is null ? null : new() { Enabled = source.Enabled, Html = source.Html, @@ -210,7 +216,7 @@ public class V2alpha1TenantController : /// The Auth0 API tenant feature flags to convert. /// A new instance with all flag values mapped from the specified API model. [return: NotNullIfNotNull(nameof(source))] - internal static V2alpha1TenantFlags? FromApi(TenantFlags? source) => source is null ? null : new() + internal static V2alpha1TenantFlags? FromApi(TenantSettingsFlags? source) => source is null ? null : new() { AllowLegacyDelegationGrantTypes = source.AllowLegacyDelegationGrantTypes, AllowLegacyRoGrantTypes = source.AllowLegacyRoGrantTypes, @@ -219,19 +225,17 @@ public class V2alpha1TenantController : DisableClickjackProtectionHeaders = source.DisableClickjackProtectionHeaders, DisableManagementApiSmsObfuscation = source.DisableManagementApiSmsObfuscation, EnableAdfsWaadEmailVerification = source.EnableAdfsWaadEmailVerification, - EnableAPIsSection = source.EnableAPIsSection, + EnableAPIsSection = source.EnableApisSection, EnableClientConnections = source.EnableClientConnections, - EnableCustomDomainInEmails = source.EnableCustomDomainInEmails, EnableDynamicClientRegistration = source.EnableDynamicClientRegistration, - EnableIdTokenApi2 = source.EnableIdTokenApi2, + EnableIdTokenApi2 = source.EnableIdtokenApi2, EnableLegacyProfile = source.EnableLegacyProfile, EnablePipeline2 = source.EnablePipeline2, EnablePublicSignupUserExistsError = source.EnablePublicSignupUserExistsError, - EnableSSO = source.EnableSSO, + EnableSSO = source.EnableSso, EnforceClientAuthenticationOnPasswordlessStart = source.EnforceClientAuthenticationOnPasswordlessStart, NoDiscloseEnterpriseConnections = source.NoDiscloseEnterpriseConnections, RemoveAlgFromJwks = source.RemoveAlgFromJwks, - RequirePushedAuthorizationRequests = source.RequirePushedAuthorizationRequests, RevokeRefreshTokenGrant = source.RevokeRefreshTokenGrant, TrustAzureAdfsEmailVerifiedConnectionProperty = source.TrustAzureAdfsEmailVerifiedConnectionProperty, DashboardInsightsView = source.DashboardInsightsView, @@ -243,7 +247,7 @@ public class V2alpha1TenantController : CustomDomainsProvisioning = source.CustomDomainsProvisioning, }; - internal static void ApplyToApi(V2alpha1TenantSettings source, TenantSettingsUpdateRequest target) + internal static void ApplyToApi(V2alpha1TenantSettings source, UpdateTenantSettingsRequestContent target) { if (source.AcrValuesSupported is { } acr_values_supported) target.AcrValuesSupported = acr_values_supported; @@ -252,10 +256,14 @@ internal static void ApplyToApi(V2alpha1TenantSettings source, TenantSettingsUpd target.AllowedLogoutUrls = allowed_logout_urls; if (source.ChangePassword is { } change_password) - ApplyToApi(change_password, target.ChangePassword = new()); + { + var v = new TenantSettingsPasswordPage(); + ApplyToApi(change_password, v); + target.ChangePassword = v; + } if (source.CustomizeMfaInPostLoginAction is { } customize_mfa_in_postlogin_action) - target.CustomizeMfaInPostLoginAction = customize_mfa_in_postlogin_action; + target.CustomizeMfaInPostloginAction = customize_mfa_in_postlogin_action; if (source.DefaultAudience is { } default_audience) target.DefaultAudience = default_audience; @@ -264,13 +272,21 @@ internal static void ApplyToApi(V2alpha1TenantSettings source, TenantSettingsUpd target.DefaultDirectory = default_directory; if (source.DeviceFlow is { } device_flow) - ApplyToApi(device_flow, target.DeviceFlow = new()); + { + var v = new TenantSettingsDeviceFlow(); + ApplyToApi(device_flow, v); + target.DeviceFlow = v; + } if (source.EnabledLocales is { } enabled_locales) - target.EnabledLocales = enabled_locales.ToArray(); + target.EnabledLocales = enabled_locales.Select(i => TenantSettingsSupportedLocalesEnum.FromCustom(i)).ToArray(); if (source.ErrorPage is { } error_page) - ApplyToApi(error_page, target.ErrorPage = new()); + { + var v = new TenantSettingsErrorPage(); + ApplyToApi(error_page, v); + target.ErrorPage = v; + } if (source.Flags is { } flags) ApplyToApi(flags, target.Flags = new()); @@ -279,13 +295,21 @@ internal static void ApplyToApi(V2alpha1TenantSettings source, TenantSettingsUpd target.FriendlyName = friendly_name; if (source.GuardianMfaPage is { } guardian_mfa_page) - ApplyToApi(guardian_mfa_page, target.GuardianMfaPage = new()); + { + var v = new TenantSettingsGuardianPage(); + ApplyToApi(guardian_mfa_page, v); + target.GuardianMfaPage = v; + } if (source.IdleSessionLifetime is { } idle_session_lifetime) - target.IdleSessionLifetime = idle_session_lifetime; + target.IdleSessionLifetime = (int?)idle_session_lifetime; if (source.Mtls is { } mtls) - ApplyToApi(mtls, target.Mtls = new()); + { + var v = new TenantSettingsMtls(); + ApplyToApi(mtls, v); + target.Mtls = v; + } if (source.PictureUrl is { } picture_url) target.PictureUrl = picture_url; @@ -296,14 +320,16 @@ internal static void ApplyToApi(V2alpha1TenantSettings source, TenantSettingsUpd if (source.SandboxVersion is { } sandbox_version) target.SandboxVersion = sandbox_version; - if (source.SandboxVersionsAvailable is { } sandbox_versions_available) - target.SandboxVersionsAvailable = sandbox_versions_available; - if (source.SessionCookie is { } session_cookie) - ApplyToApi(session_cookie, target.SessionCookie = new()); + { + if (session_cookie.Mode is { } mode) + { + target.SessionCookie = new SessionCookieSchema() { Mode = SessionCookieModeEnum.FromCustom(mode) }; + } + } if (source.SessionLifetime is { } session_lifetime) - target.SessionLifetime = session_lifetime; + target.SessionLifetime = (int?)session_lifetime; if (source.SupportEmail is { } support_email) target.SupportEmail = support_email; @@ -312,7 +338,7 @@ internal static void ApplyToApi(V2alpha1TenantSettings source, TenantSettingsUpd target.SupportUrl = support_url; } - internal static void ApplyToApi(V2alpha1TenantChangePassword source, TenantChangePassword target) + internal static void ApplyToApi(V2alpha1TenantChangePassword source, TenantSettingsPasswordPage target) { if (source.Enabled is { } enabled) target.Enabled = enabled; @@ -321,7 +347,7 @@ internal static void ApplyToApi(V2alpha1TenantChangePassword source, TenantChang target.Html = html; } - internal static void ApplyToApi(V2alpha1TenantDeviceFlow source, TenantDeviceFlow target) + internal static void ApplyToApi(V2alpha1TenantDeviceFlow source, TenantSettingsDeviceFlow target) { if (source.Charset is { } charset) target.Charset = ToApi(charset); @@ -330,14 +356,14 @@ internal static void ApplyToApi(V2alpha1TenantDeviceFlow source, TenantDeviceFlo target.Mask = mask; } - internal static TenantDeviceFlowCharset ToApi(V2alpha1TenantCharset charset) => charset switch + internal static TenantSettingsDeviceFlowCharset ToApi(V2alpha1TenantCharset charset) => charset switch { - V2alpha1TenantCharset.Base20 => TenantDeviceFlowCharset.Base20, - V2alpha1TenantCharset.Digits => TenantDeviceFlowCharset.Digits, + V2alpha1TenantCharset.Base20 => TenantSettingsDeviceFlowCharset.Base20, + V2alpha1TenantCharset.Digits => TenantSettingsDeviceFlowCharset.Digits, _ => throw new NotImplementedException(), }; - internal static void ApplyToApi(V2alpha1TenantErrorPage source, TenantErrorPage target) + internal static void ApplyToApi(V2alpha1TenantErrorPage source, TenantSettingsErrorPage target) { if (source.ShowLogLink is { } show_log_link) target.ShowLogLink = show_log_link; @@ -349,7 +375,7 @@ internal static void ApplyToApi(V2alpha1TenantErrorPage source, TenantErrorPage target.Html = html; } - internal static void ApplyToApi(V2alpha1TenantFlags source, TenantFlags target) + internal static void ApplyToApi(V2alpha1TenantFlags source, TenantSettingsFlags target) { if (source.AllowLegacyDelegationGrantTypes is { } allow_legacy_delegation_grant_types) target.AllowLegacyDelegationGrantTypes = allow_legacy_delegation_grant_types; @@ -373,19 +399,16 @@ internal static void ApplyToApi(V2alpha1TenantFlags source, TenantFlags target) target.EnableAdfsWaadEmailVerification = enable_adfs_waad_email_verification; if (source.EnableAPIsSection is { } enable_apis_section) - target.EnableAPIsSection = enable_apis_section; + target.EnableApisSection = enable_apis_section; if (source.EnableClientConnections is { } enable_client_connections) target.EnableClientConnections = enable_client_connections; - if (source.EnableCustomDomainInEmails is { } enable_custom_domain_in_emails) - target.EnableCustomDomainInEmails = enable_custom_domain_in_emails; - if (source.EnableDynamicClientRegistration is { } enable_dynamic_client_registration) target.EnableDynamicClientRegistration = enable_dynamic_client_registration; if (source.EnableIdTokenApi2 is { } enable_id_token_api2) - target.EnableIdTokenApi2 = enable_id_token_api2; + target.EnableIdtokenApi2 = enable_id_token_api2; if (source.EnableLegacyProfile is { } enable_legacy_profile) target.EnableLegacyProfile = enable_legacy_profile; @@ -397,7 +420,7 @@ internal static void ApplyToApi(V2alpha1TenantFlags source, TenantFlags target) target.EnablePublicSignupUserExistsError = enable_public_signup_user_exists_error; if (source.EnableSSO is { } enable_sso) - target.EnableSSO = enable_sso; + target.EnableSso = enable_sso; if (source.EnforceClientAuthenticationOnPasswordlessStart is { } enforce_client_authentication_on_passwordless_start) target.EnforceClientAuthenticationOnPasswordlessStart = enforce_client_authentication_on_passwordless_start; @@ -408,9 +431,6 @@ internal static void ApplyToApi(V2alpha1TenantFlags source, TenantFlags target) if (source.RemoveAlgFromJwks is { } remove_alg_from_jwks) target.RemoveAlgFromJwks = remove_alg_from_jwks; - if (source.RequirePushedAuthorizationRequests is { } require_pushed_authorization_requests) - target.RequirePushedAuthorizationRequests = require_pushed_authorization_requests; - if (source.RevokeRefreshTokenGrant is { } revoke_refresh_token_grant) target.RevokeRefreshTokenGrant = revoke_refresh_token_grant; @@ -439,7 +459,7 @@ internal static void ApplyToApi(V2alpha1TenantFlags source, TenantFlags target) target.CustomDomainsProvisioning = custom_domains_provisioning; } - internal static void ApplyToApi(V2alpha1TenantGuardianMfaPage source, TenantGuardianMfaPage target) + internal static void ApplyToApi(V2alpha1TenantGuardianMfaPage source, TenantSettingsGuardianPage target) { if (source.Enabled is { } enabled) target.Enabled = enabled; @@ -448,19 +468,19 @@ internal static void ApplyToApi(V2alpha1TenantGuardianMfaPage source, TenantGuar target.Html = html; } - internal static void ApplyToApi(V2alpha1TenantMtls source, TenantMtls target) + internal static void ApplyToApi(V2alpha1TenantMtls source, TenantSettingsMtls target) { if (source.EnableEndpointAliases is { } enable_endpoint_aliases) target.EnableEndpointAliases = enable_endpoint_aliases; } - internal static void ApplyToApi(V2alpha1TenantSessionCookie source, SessionCookie target) + internal static void ApplyToApi(V2alpha1TenantSessionCookie source, SessionCookieSchema target) { if (source.Mode is { } mode) - target.Mode = mode; + target.Mode = SessionCookieModeEnum.FromCustom(mode); } - internal static void ApplyToApi(V2alpha1TenantPrompts source, PromptUpdateRequest target) + internal static void ApplyToApi(V2alpha1TenantPrompts source, UpdateSettingsRequestContent target) { if (source.IdentifierFirst is { } identifier_first) target.IdentifierFirst = identifier_first; @@ -469,14 +489,14 @@ internal static void ApplyToApi(V2alpha1TenantPrompts source, PromptUpdateReques target.UniversalLoginExperience = ToApi(universal_login_experience); } - internal static string ToApi(V2alpha1TenantUniversalLoginExperience source) => source switch + internal static UniversalLoginExperienceEnum ToApi(V2alpha1TenantUniversalLoginExperience source) => source switch { - V2alpha1TenantUniversalLoginExperience.New => "new", - V2alpha1TenantUniversalLoginExperience.Classic => "classic", + V2alpha1TenantUniversalLoginExperience.New => UniversalLoginExperienceEnum.FromCustom(UniversalLoginExperienceEnum.Values.New), + V2alpha1TenantUniversalLoginExperience.Classic => UniversalLoginExperienceEnum.FromCustom(UniversalLoginExperienceEnum.Values.Classic), _ => throw new NotImplementedException(), }; - internal static void ApplyToApi(V2alpha1TenantBranding source, BrandingUpdateRequest target) + internal static void ApplyToApi(V2alpha1TenantBranding source, UpdateBrandingRequestContent target) { if (source.LogoUrl is { } logo_url) target.LogoUrl = logo_url; @@ -485,16 +505,20 @@ internal static void ApplyToApi(V2alpha1TenantBranding source, BrandingUpdateReq target.FaviconUrl = favicon_url; if (source.Colors is { } colors) - ApplyToApi(colors, target.Colors = new()); + { + var v = new UpdateBrandingColors(); + ApplyToApi(colors, v); + target.Colors = v; + } } - internal static void ApplyToApi(V2alpha1TenantBrandingColors source, BrandingColors target) + internal static void ApplyToApi(V2alpha1TenantBrandingColors source, UpdateBrandingColors target) { if (source.Primary is { } primary) target.Primary = primary; if (source.PageBackground is { } page_background) - target.PageBackground = page_background; + target.PageBackground = UpdateBrandingPageBackground.FromString(page_background); } /// @@ -520,7 +544,7 @@ protected override async Task Reconcile(V2alpha1Tenant entity, CancellationToken if (api == null) throw new RetryException($"{EntityTypeName} {entity.Namespace()}:{entity.Name()} failed to retrieve API client."); - var settings = await api.TenantSettings.GetAsync(cancellationToken: cancellationToken); + var settings = await api.Tenants.Settings.GetAsync(new GetTenantSettingsRequestParameters() { }, cancellationToken: cancellationToken); if (settings is null) throw new RetryException($"{EntityTypeName} {entity.Namespace()}/{entity.Name()} settings cannot be loaded from API."); @@ -528,7 +552,7 @@ protected override async Task Reconcile(V2alpha1Tenant entity, CancellationToken if (branding is null) throw new RetryException($"{EntityTypeName} {entity.Namespace()}/{entity.Name()} branding cannot be loaded from API."); - var prompts = await api.Prompts.GetAsync(cancellationToken: cancellationToken); + var prompts = await api.Prompts.GetSettingsAsync(cancellationToken: cancellationToken); if (prompts is null) throw new RetryException($"{EntityTypeName} {entity.Namespace()}/{entity.Name()} prompts cannot be loaded from API."); @@ -539,32 +563,35 @@ protected override async Task Reconcile(V2alpha1Tenant entity, CancellationToken if (conf.Settings is { } newSettings) { // verify that no changes to enable_sso are being made - if (newSettings.Flags != null && newSettings.Flags.EnableSSO != null && settings.Flags.EnableSSO != null && newSettings.Flags.EnableSSO != settings.Flags.EnableSSO) + if (newSettings.Flags != null && newSettings.Flags.EnableSSO != null && settings.Flags.EnableSso != null && newSettings.Flags.EnableSSO != settings.Flags.EnableSso) throw new RetryException($"{EntityTypeName} {entity.Namespace()}/{entity.Name()}: updating the enable_sso flag is not allowed."); // push update to Auth0 - var req = new TenantSettingsUpdateRequest(); + var req = new UpdateTenantSettingsRequestContent(); ApplyToApi(newSettings, req); - req.Flags.EnableSSO = null; // this can never be passed - settings = await api.TenantSettings.UpdateAsync(req, cancellationToken); + req.Flags.EnableSso = null; // this can never be passed + var res = await api.Tenants.Settings.UpdateAsync(req, cancellationToken: cancellationToken); + settings = await api.Tenants.Settings.GetAsync(new GetTenantSettingsRequestParameters() { }, cancellationToken: cancellationToken); } // branding may not be specified if (conf.Branding is { } newBranding) { // push update to Auth0 - var req = new BrandingUpdateRequest(); + var req = new UpdateBrandingRequestContent(); ApplyToApi(newBranding, req); - branding = await api.Branding.UpdateAsync(req, cancellationToken); + var res = await api.Branding.UpdateAsync(req, cancellationToken: cancellationToken); + branding = await api.Branding.GetAsync(cancellationToken: cancellationToken); } // prompts may not be specified if (conf.Prompts is { } newPrompts) { // push update to Auth0 - var req = new PromptUpdateRequest(); + var req = new UpdateSettingsRequestContent(); ApplyToApi(newPrompts, req); - prompts = await api.Prompts.UpdateAsync(req, cancellationToken); + await api.Prompts.UpdateSettingsAsync(req, cancellationToken: cancellationToken); + prompts = await api.Prompts.GetSettingsAsync(cancellationToken: cancellationToken); } } diff --git a/src/Alethic.Auth0.Operator/Converters/ClientConverter.cs b/src/Alethic.Auth0.Operator/Converters/ClientConverter.cs new file mode 100644 index 0000000..6dd2ff7 --- /dev/null +++ b/src/Alethic.Auth0.Operator/Converters/ClientConverter.cs @@ -0,0 +1,412 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Versioning; +using System.Text.Json; +using System.Linq; + +using Alethic.Auth0.Operator.Controllers; +using Alethic.Auth0.Operator.Core.Models; +using Alethic.Auth0.Operator.Core.Models.Client.V1; +using Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; +using Alethic.Auth0.Operator.Models; + +using Auth0.ManagementApi; + +using KubeOps.Operator.Web.Webhooks.Conversion; + +namespace Alethic.Auth0.Operator.Converters +{ + + using V2alpha1ClientEntity = Models.V2alpha1Client; + + [RequiresPreviewFeatures] + [ConversionWebhook(typeof(V2alpha1ClientEntity))] + public class ClientConverter : ConversionWebhook + { + + protected override IEnumerable> Converters => [ + new V1ToV2alpha1() + ]; + + class V1ToV2alpha1 : IEntityConverter + { + + static readonly JsonSerializerOptions Auth0JsonSerializerOptions = CreateAuth0JsonSerializerOptions(); + + public V2alpha1ClientEntity Convert(V1Client from) + { + var result = new V2alpha1ClientEntity { Metadata = from.Metadata }; + result.Spec.Policy = from.Spec.Policy; + result.Spec.TenantRef = from.Spec.TenantRef; + result.Spec.SecretRef = from.Spec.SecretRef; + result.Spec.Find = from.Spec.Find is { } find ? new V2alpha1ClientFind { ClientId = find.ClientId, Name = find.Name } : null; + result.Spec.Init = ConvertConf(from.Spec.Init); + result.Spec.Conf = ConvertConf(from.Spec.Conf); + result.Status.Id = from.Status.Id; + result.Status.LastConf = ConvertConf(from.Status.LastConf); + return result; + } + + public V1Client Revert(V2alpha1ClientEntity source) + { + var result = new V1Client { Metadata = source.Metadata }; + result.Spec.Policy = source.Spec.Policy; + result.Spec.TenantRef = source.Spec.TenantRef; + result.Spec.SecretRef = source.Spec.SecretRef; + result.Spec.Find = source.Spec.Find is { } find ? new V1ClientFind { ClientId = find.ClientId, Name = find.Name } : null; + result.Spec.Init = RevertConf(source.Spec.Init); + result.Spec.Conf = RevertConf(source.Spec.Conf); + result.Status.Id = source.Status.Id; + result.Status.LastConf = RevertConf(source.Status.LastConf); + return result; + } + + static V2alpha1ClientConf? ConvertConf(V1ClientConf? source) + { + if (source is null) + return null; + + return new V2alpha1ClientConf + { + AllowedClients = source.AllowedClients, + AllowedLogoutUrls = source.AllowedLogoutUrls, + AllowedOrigins = source.AllowedOrigins, + WebOrigins = source.WebOrigins, + InitiateLoginUri = source.InitiateLoginUri, + Callbacks = source.Callbacks, + ClientAliases = source.ClientAliases, + ClientMetaData = source.ClientMetaData, + IsCustomLoginPageOn = source.IsCustomLoginPageOn, + IsFirstParty = source.IsFirstParty, + CustomLoginPage = source.CustomLoginPage, + CustomLoginPagePreview = source.CustomLoginPagePreview, + FormTemplate = source.FormTemplate, + GrantTypes = source.GrantTypes, + Name = source.Name, + Description = source.Description, + LogoUri = source.LogoUri, + OidcConformant = source.OidcConformant, + Sso = source.Sso, + CrossOriginAuthentication = source.CrossOriginAuthentication, + RequirePushedAuthorizationRequests = source.RequirePushedAuthorizationRequests, + RequireProofOfPossession = source.RequireProofOfPossession, + ResourceServers = null, + AddOns = source.AddOns is { } addons ? ConvertAddons(addons) : null, + ApplicationType = source.ApplicationType is { } applicationType ? ConvertApplicationType(applicationType) : null, + ComplianceLevel = source.ComplianceLevel is { } complianceLevel ? ConvertComplianceLevel(complianceLevel) : null, + DefaultOrganization = source.DefaultOrganization is { } defaultOrganization ? ConvertWithAuth0(defaultOrganization, V2alpha1ClientController.FromApi) : null, + EncryptionKey = source.EncryptionKey is { } encryptionKey ? ConvertWithAuth0(encryptionKey, V2alpha1ClientController.FromApi) : null, + JwtConfiguration = source.JwtConfiguration is { } jwtConfiguration ? ConvertWithAuth0(jwtConfiguration, V2alpha1ClientController.FromApi) : null, + Mobile = source.Mobile is { } mobile ? ConvertWithAuth0(mobile, V2alpha1ClientController.FromApi) : null, + OidcLogout = source.OidcLogout is { } oidcLogout ? ConvertWithAuth0(oidcLogout, V2alpha1ClientController.FromApi) : null, + OrganizationRequireBehavior = source.OrganizationRequireBehavior is { } organizationRequireBehavior ? ConvertOrganizationRequireBehavior(organizationRequireBehavior) : null, + OrganizationUsage = source.OrganizationUsage is { } organizationUsage ? ConvertOrganizationUsage(organizationUsage) : null, + RefreshToken = source.RefreshToken is { } refreshToken ? ConvertWithAuth0(refreshToken, V2alpha1ClientController.FromApi) : null, + SigningKeys = source.SigningKeys is { Length: > 0 } signingKeys ? [.. signingKeys.Select(signingKey => ConvertWithAuth0(signingKey, V2alpha1ClientController.FromApi)!)] : null, + TokenEndpointAuthMethod = source.TokenEndpointAuthMethod is { } tokenEndpointAuthMethod ? ConvertTokenEndpointAuthMethod(tokenEndpointAuthMethod) : null, + }; + } + + static V1ClientConf? RevertConf(V2alpha1ClientConf? source) + { + if (source is null) + return null; + + return new V1ClientConf + { + AllowedClients = source.AllowedClients, + AllowedLogoutUrls = source.AllowedLogoutUrls, + AllowedOrigins = source.AllowedOrigins, + WebOrigins = source.WebOrigins, + InitiateLoginUri = source.InitiateLoginUri, + Callbacks = source.Callbacks, + ClientAliases = source.ClientAliases, + ClientMetaData = source.ClientMetaData, + IsCustomLoginPageOn = source.IsCustomLoginPageOn, + IsFirstParty = source.IsFirstParty, + CustomLoginPage = source.CustomLoginPage, + CustomLoginPagePreview = source.CustomLoginPagePreview, + FormTemplate = source.FormTemplate, + GrantTypes = source.GrantTypes, + Name = source.Name, + Description = source.Description, + LogoUri = source.LogoUri, + OidcConformant = source.OidcConformant, + Sso = source.Sso, + CrossOriginAuthentication = source.CrossOriginAuthentication, + RequirePushedAuthorizationRequests = source.RequirePushedAuthorizationRequests, + RequireProofOfPossession = source.RequireProofOfPossession, + ResourceServers = null, + AddOns = source.AddOns is { } addons ? RevertAddons(addons) : null, + ApplicationType = source.ApplicationType is { } applicationType ? RevertApplicationType(applicationType) : null, + ComplianceLevel = source.ComplianceLevel is { } complianceLevel ? RevertComplianceLevel(complianceLevel) : null, + DefaultOrganization = source.DefaultOrganization is { } defaultOrganization ? RevertWithAuth0(defaultOrganization, ToApi) : null, + EncryptionKey = source.EncryptionKey is { } encryptionKey ? RevertWithAuth0(encryptionKey, ToApi) : null, + JwtConfiguration = source.JwtConfiguration is { } jwtConfiguration ? RevertWithAuth0(jwtConfiguration, ToApi) : null, + Mobile = source.Mobile is { } mobile ? RevertWithAuth0(mobile, ToApi) : null, + OidcLogout = source.OidcLogout is { } oidcLogout ? RevertWithAuth0(oidcLogout, ToApi) : null, + OrganizationRequireBehavior = source.OrganizationRequireBehavior is { } organizationRequireBehavior ? RevertOrganizationRequireBehavior(organizationRequireBehavior) : null, + OrganizationUsage = source.OrganizationUsage is { } organizationUsage ? RevertOrganizationUsage(organizationUsage) : null, + RefreshToken = source.RefreshToken is { } refreshToken ? RevertWithAuth0(refreshToken, ToApi) : null, + SigningKeys = source.SigningKeys is { Length: > 0 } signingKeys ? [.. signingKeys.Select(RevertSigningKey)] : null, + TokenEndpointAuthMethod = source.TokenEndpointAuthMethod is { } tokenEndpointAuthMethod ? RevertTokenEndpointAuthMethod(tokenEndpointAuthMethod) : null, + }; + } + + static V2alpha1ClientComplianceLevelEnum ConvertComplianceLevel(V1ClientComplianceLevel source) => source switch + { + V1ClientComplianceLevel.None => V2alpha1ClientComplianceLevelEnum.None, + V1ClientComplianceLevel.Fapi1AdvPkjPar => V2alpha1ClientComplianceLevelEnum.Fapi1AdvPkjPar, + V1ClientComplianceLevel.Fapi1AdvMtlsPar => V2alpha1ClientComplianceLevelEnum.Fapi1AdvMtlsPar, + _ => throw new NotImplementedException(), + }; + + static V1ClientComplianceLevel RevertComplianceLevel(V2alpha1ClientComplianceLevelEnum source) => source switch + { + V2alpha1ClientComplianceLevelEnum.None => V1ClientComplianceLevel.None, + V2alpha1ClientComplianceLevelEnum.Fapi1AdvPkjPar => V1ClientComplianceLevel.Fapi1AdvPkjPar, + V2alpha1ClientComplianceLevelEnum.Fapi1AdvMtlsPar => V1ClientComplianceLevel.Fapi1AdvMtlsPar, + _ => throw new NotImplementedException(), + }; + + static V2alpha1ClientOrganizationRequireBehaviorEnum ConvertOrganizationRequireBehavior(V1ClientOrganizationRequireBehavior source) => source switch + { + V1ClientOrganizationRequireBehavior.NoPrompt => V2alpha1ClientOrganizationRequireBehaviorEnum.NoPrompt, + V1ClientOrganizationRequireBehavior.PreLoginPrompt => V2alpha1ClientOrganizationRequireBehaviorEnum.PreLoginPrompt, + V1ClientOrganizationRequireBehavior.PostLoginPrompt => V2alpha1ClientOrganizationRequireBehaviorEnum.PostLoginPrompt, + _ => throw new NotImplementedException(), + }; + + static V1ClientOrganizationRequireBehavior RevertOrganizationRequireBehavior(V2alpha1ClientOrganizationRequireBehaviorEnum source) => source switch + { + V2alpha1ClientOrganizationRequireBehaviorEnum.NoPrompt => V1ClientOrganizationRequireBehavior.NoPrompt, + V2alpha1ClientOrganizationRequireBehaviorEnum.PreLoginPrompt => V1ClientOrganizationRequireBehavior.PreLoginPrompt, + V2alpha1ClientOrganizationRequireBehaviorEnum.PostLoginPrompt => V1ClientOrganizationRequireBehavior.PostLoginPrompt, + _ => throw new NotImplementedException(), + }; + + static V2alpha1ClientOrganizationUsageEnum ConvertOrganizationUsage(V1ClientOrganizationUsage source) => source switch + { + V1ClientOrganizationUsage.Deny => V2alpha1ClientOrganizationUsageEnum.Deny, + V1ClientOrganizationUsage.Allow => V2alpha1ClientOrganizationUsageEnum.Allow, + V1ClientOrganizationUsage.Require => V2alpha1ClientOrganizationUsageEnum.Require, + _ => throw new NotImplementedException(), + }; + + static V1ClientOrganizationUsage RevertOrganizationUsage(V2alpha1ClientOrganizationUsageEnum source) => source switch + { + V2alpha1ClientOrganizationUsageEnum.Deny => V1ClientOrganizationUsage.Deny, + V2alpha1ClientOrganizationUsageEnum.Allow => V1ClientOrganizationUsage.Allow, + V2alpha1ClientOrganizationUsageEnum.Require => V1ClientOrganizationUsage.Require, + _ => throw new NotImplementedException(), + }; + + static V2alpha1ClientAppTypeEnum ConvertApplicationType(V1ClientApplicationType source) + { + return source switch + { + V1ClientApplicationType.Box => V2alpha1ClientAppTypeEnum.Box, + V1ClientApplicationType.Cloudbees => V2alpha1ClientAppTypeEnum.Cloudbees, + V1ClientApplicationType.Concur => V2alpha1ClientAppTypeEnum.Concur, + V1ClientApplicationType.Dropbox => V2alpha1ClientAppTypeEnum.Dropbox, + V1ClientApplicationType.Echosign => V2alpha1ClientAppTypeEnum.Echosign, + V1ClientApplicationType.Egnyte => V2alpha1ClientAppTypeEnum.Egnyte, + V1ClientApplicationType.MsCrm => V2alpha1ClientAppTypeEnum.Mscrm, + V1ClientApplicationType.Native => V2alpha1ClientAppTypeEnum.Native, + V1ClientApplicationType.NewRelic => V2alpha1ClientAppTypeEnum.Newrelic, + V1ClientApplicationType.NonInteractive => V2alpha1ClientAppTypeEnum.NonInteractive, + V1ClientApplicationType.Office365 => V2alpha1ClientAppTypeEnum.Office365, + V1ClientApplicationType.RegularWeb => V2alpha1ClientAppTypeEnum.RegularWeb, + V1ClientApplicationType.Rms => V2alpha1ClientAppTypeEnum.Rms, + V1ClientApplicationType.Salesforce => V2alpha1ClientAppTypeEnum.Salesforce, + V1ClientApplicationType.Sentry => V2alpha1ClientAppTypeEnum.Sentry, + V1ClientApplicationType.SharePoint => V2alpha1ClientAppTypeEnum.Sharepoint, + V1ClientApplicationType.Slack => V2alpha1ClientAppTypeEnum.Slack, + V1ClientApplicationType.SpringCm => V2alpha1ClientAppTypeEnum.Springcm, + V1ClientApplicationType.Spa => V2alpha1ClientAppTypeEnum.Spa, + V1ClientApplicationType.Zendesk => V2alpha1ClientAppTypeEnum.Zendesk, + V1ClientApplicationType.Zoom => V2alpha1ClientAppTypeEnum.Zoom, + V1ClientApplicationType.ResourceServer => V2alpha1ClientAppTypeEnum.ResourceServer, + V1ClientApplicationType.ExpressConfiguration => V2alpha1ClientAppTypeEnum.ExpressConfiguration, + V1ClientApplicationType.SsoIntegration => V2alpha1ClientAppTypeEnum.SsoIntegration, + V1ClientApplicationType.Oag => V2alpha1ClientAppTypeEnum.Oag, + _ => throw new NotImplementedException(), + }; + } + + static V1ClientApplicationType RevertApplicationType(V2alpha1ClientAppTypeEnum source) => source switch + { + V2alpha1ClientAppTypeEnum.Box => V1ClientApplicationType.Box, + V2alpha1ClientAppTypeEnum.Cloudbees => V1ClientApplicationType.Cloudbees, + V2alpha1ClientAppTypeEnum.Concur => V1ClientApplicationType.Concur, + V2alpha1ClientAppTypeEnum.Dropbox => V1ClientApplicationType.Dropbox, + V2alpha1ClientAppTypeEnum.Echosign => V1ClientApplicationType.Echosign, + V2alpha1ClientAppTypeEnum.Egnyte => V1ClientApplicationType.Egnyte, + V2alpha1ClientAppTypeEnum.Mscrm => V1ClientApplicationType.MsCrm, + V2alpha1ClientAppTypeEnum.Native => V1ClientApplicationType.Native, + V2alpha1ClientAppTypeEnum.Newrelic => V1ClientApplicationType.NewRelic, + V2alpha1ClientAppTypeEnum.NonInteractive => V1ClientApplicationType.NonInteractive, + V2alpha1ClientAppTypeEnum.Office365 => V1ClientApplicationType.Office365, + V2alpha1ClientAppTypeEnum.RegularWeb => V1ClientApplicationType.RegularWeb, + V2alpha1ClientAppTypeEnum.Rms => V1ClientApplicationType.Rms, + V2alpha1ClientAppTypeEnum.Salesforce => V1ClientApplicationType.Salesforce, + V2alpha1ClientAppTypeEnum.Sentry => V1ClientApplicationType.Sentry, + V2alpha1ClientAppTypeEnum.Sharepoint => V1ClientApplicationType.SharePoint, + V2alpha1ClientAppTypeEnum.Slack => V1ClientApplicationType.Slack, + V2alpha1ClientAppTypeEnum.Springcm => V1ClientApplicationType.SpringCm, + V2alpha1ClientAppTypeEnum.Spa => V1ClientApplicationType.Spa, + V2alpha1ClientAppTypeEnum.Zendesk => V1ClientApplicationType.Zendesk, + V2alpha1ClientAppTypeEnum.Zoom => V1ClientApplicationType.Zoom, + V2alpha1ClientAppTypeEnum.ResourceServer => V1ClientApplicationType.ResourceServer, + V2alpha1ClientAppTypeEnum.ExpressConfiguration => V1ClientApplicationType.ExpressConfiguration, + V2alpha1ClientAppTypeEnum.SsoIntegration => V1ClientApplicationType.SsoIntegration, + V2alpha1ClientAppTypeEnum.Oag => V1ClientApplicationType.Oag, + _ => throw new NotImplementedException(), + }; + + static V2alpha1ClientTokenEndpointAuthMethodEnum ConvertTokenEndpointAuthMethod(V1ClientTokenEndpointAuthMethod source) => source switch + { + V1ClientTokenEndpointAuthMethod.None => V2alpha1ClientTokenEndpointAuthMethodEnum.None, + V1ClientTokenEndpointAuthMethod.ClientSecretPost => V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretPost, + V1ClientTokenEndpointAuthMethod.ClientSecretBasic => V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretBasic, + _ => throw new NotImplementedException(), + }; + + static V1ClientTokenEndpointAuthMethod RevertTokenEndpointAuthMethod(V2alpha1ClientTokenEndpointAuthMethodEnum source) => source switch + { + V2alpha1ClientTokenEndpointAuthMethodEnum.None => V1ClientTokenEndpointAuthMethod.None, + V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretPost => V1ClientTokenEndpointAuthMethod.ClientSecretPost, + V2alpha1ClientTokenEndpointAuthMethodEnum.ClientSecretBasic => V1ClientTokenEndpointAuthMethod.ClientSecretBasic, + _ => throw new NotImplementedException(), + }; + + static ClientDefaultOrganization ToApi(V2alpha1ClientDefaultOrganization source) => new() + { + OrganizationId = source.OrganizationId, + Flows = source.Flows?.Select(ToApi).ToArray(), + }; + + static ClientDefaultOrganizationFlowsEnum ToApi(V2alpha1ClientDefaultOrganizationFlowsEnum source) => source switch + { + V2alpha1ClientDefaultOrganizationFlowsEnum.ClientCredentials => new ClientDefaultOrganizationFlowsEnum(ClientDefaultOrganizationFlowsEnum.Values.ClientCredentials), + _ => throw new NotImplementedException(), + }; + + static ClientEncryptionKey ToApi(V2alpha1ClientEncryptionKey source) + { + var result = new ClientEncryptionKey(); + V2alpha1ClientController.ApplyToApi(source, result); + return result; + } + + static ClientJwtConfiguration ToApi(V2alpha1ClientJwtConfiguration source) + { + var result = new ClientJwtConfiguration(); + V2alpha1ClientController.ApplyToApi(source, result); + return result; + } + + static ClientMobile ToApi(V2alpha1ClientMobile source) + { + var result = new ClientMobile(); + V2alpha1ClientController.ApplyToApi(source, result); + return result; + } + + static ClientOidcBackchannelLogoutSettings ToApi(V2alpha1ClientOidcBackchannelLogoutSettings source) + { + var result = new ClientOidcBackchannelLogoutSettings(); + V2alpha1ClientController.ApplyToApi(source, result); + return result; + } + + static ClientRefreshTokenConfiguration ToApi(V2alpha1ClientRefreshTokenConfiguration source) + { + var result = new ClientRefreshTokenConfiguration + { + RotationType = source.RotationType is { } rotationType ? V2alpha1ClientController.ToApi(rotationType) : new RefreshTokenRotationTypeEnum(RefreshTokenRotationTypeEnum.Values.NonRotating), + ExpirationType = source.ExpirationType is { } expirationType ? V2alpha1ClientController.ToApi(expirationType) : new RefreshTokenExpirationTypeEnum(RefreshTokenExpirationTypeEnum.Values.NonExpiring), + }; + V2alpha1ClientController.ApplyToApi(source, result); + return result; + } + + static V1ClientSigningKey RevertSigningKey(V2alpha1ClientSigningKey source) + { + var api = new ClientSigningKey + { + Cert = source.Cert, + Pkcs7 = source.Pkcs7, + Subject = source.Subject, + }; + + return SerializeAndDeserialize(api); + } + + static V2alpha1ClientAddons? ConvertAddons(V1ClientAddons? source) + { + if (source is null) + return null; + + var api = Deserialize(source); + return V2alpha1ClientController.FromApi(api); + } + + static V1ClientAddons? RevertAddons(V2alpha1ClientAddons? source) + { + if (source is null) + return null; + + return SerializeAndDeserialize(V2alpha1ClientController.ToApi(source)); + } + + static TTarget? ConvertWithAuth0(TSource? source, Func converter) + where TSource : class + where TApi : class + where TTarget : class + { + if (source is null) + return null; + + var api = Deserialize(source); + return converter(api); + } + + static TV1? RevertWithAuth0(TSource? source, Func toApi) + where TSource : class + where TApi : class + where TV1 : class + { + if (source is null) + return null; + + return SerializeAndDeserialize(toApi(source)); + } + + static T Deserialize(object source) where T : class + { + return JsonSerializer.Deserialize(JsonSerializer.Serialize(source, Auth0JsonSerializerOptions), Auth0JsonSerializerOptions) + ?? throw new InvalidOperationException($"Unable to deserialize {typeof(T).Name}."); + } + + static T SerializeAndDeserialize(object source) + { + return JsonSerializer.Deserialize(JsonSerializer.Serialize(source, Auth0JsonSerializerOptions)) + ?? throw new InvalidOperationException($"Unable to deserialize {typeof(T).Name}."); + } + + static JsonSerializerOptions CreateAuth0JsonSerializerOptions() + { + var type = typeof(GetClientResponseContent).Assembly.GetType("Auth0.ManagementApi.Core.JsonOptions") + ?? throw new InvalidOperationException("Unable to locate Auth0.ManagementApi.Core.JsonOptions."); + + return type.GetField("JsonSerializerOptions", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)?.GetValue(null) as JsonSerializerOptions + ?? throw new InvalidOperationException("Unable to resolve Auth0 JSON serializer options."); + } + + } + + } + +} diff --git a/src/Alethic.Auth0.Operator/Converters/ConnectionConverter.cs b/src/Alethic.Auth0.Operator/Converters/ConnectionConverter.cs new file mode 100644 index 0000000..d399876 --- /dev/null +++ b/src/Alethic.Auth0.Operator/Converters/ConnectionConverter.cs @@ -0,0 +1,316 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Versioning; +using System.Text.Json; + +using Alethic.Auth0.Operator.Controllers; +using Alethic.Auth0.Operator.Core.Models.Connection.V1; +using Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; +using Alethic.Auth0.Operator.Models; + +using Auth0.ManagementApi; +using Auth0.ManagementApi.Connections; + +using KubeOps.Operator.Web.Webhooks.Conversion; + +namespace Alethic.Auth0.Operator.Converters +{ + + /// + /// Provides conversions targeting . + /// + [RequiresPreviewFeatures] + [ConversionWebhook(typeof(V2alpha1Connection))] + public class ConnectionConverter : ConversionWebhook + { + + protected override IEnumerable> Converters => [ + new V1ToV2alpha1() + ]; + + /// + /// Converts between and . + /// + class V1ToV2alpha1 : IEntityConverter + { + + static readonly JsonSerializerOptions Auth0JsonSerializerOptions = CreateAuth0JsonSerializerOptions(); + + public V2alpha1Connection Convert(V1Connection from) + { + var result = new V2alpha1Connection { Metadata = from.Metadata }; + result.Spec.Policy = from.Spec.Policy; + result.Spec.TenantRef = from.Spec.TenantRef; + result.Spec.Find = from.Spec.Find is { } find ? new V2alpha1ConnectionFind { ConnectionId = find.ConnectionId } : null; + result.Spec.Init = ConvertConf(from.Spec.Init); + result.Spec.Conf = ConvertConf(from.Spec.Conf); + result.Status.Id = from.Status.Id; + result.Status.LastConf = ConvertConf(from.Status.LastConf); + return result; + } + + public V1Connection Revert(V2alpha1Connection source) + { + var result = new V1Connection { Metadata = source.Metadata }; + result.Spec.Policy = source.Spec.Policy; + result.Spec.TenantRef = source.Spec.TenantRef; + result.Spec.Find = source.Spec.Find is { } find ? new V1ConnectionFind { ConnectionId = find.ConnectionId } : null; + result.Spec.Init = RevertConf(source.Spec.Init); + result.Spec.Conf = RevertConf(source.Spec.Conf); + result.Status.Id = source.Status.Id; + result.Status.LastConf = RevertConf(source.Status.LastConf); + return result; + } + + static V2alpha1ConnectionConf? ConvertConf(V1ConnectionConf? source) + { + if (source is null) + return null; + + var strategy = source.Strategy is { } s ? JsonSerializer.Deserialize(JsonSerializer.Serialize(s)) : null; + + return new V2alpha1ConnectionConf + { + Name = source.Name, + DisplayName = source.DisplayName, + Strategy = strategy, + ProvisioningTicketUrl = source.ProvisioningTicketUrl, + Metadata = source.Metadata, + Realms = source.Realms, + EnabledClients = source.EnabledClients, + ShowAsButton = source.ShowAsButton, + IsDomainConnection = source.IsDomainConnection, + Options = ConvertOptions(strategy, source.Options), + }; + } + + static V1ConnectionConf? RevertConf(V2alpha1ConnectionConf? source) + { + if (source is null) + return null; + + return new V1ConnectionConf + { + Name = source.Name, + DisplayName = source.DisplayName, + Strategy = source.Strategy is { } sv ? JsonSerializer.SerializeToElement(sv).GetString() : null, + ProvisioningTicketUrl = source.ProvisioningTicketUrl, + Metadata = source.Metadata, + Realms = source.Realms, + EnabledClients = source.EnabledClients, + ShowAsButton = source.ShowAsButton, + IsDomainConnection = source.IsDomainConnection, + Options = RevertOptions(source.Strategy, source.Options), + + }; + } + + static V2alpha1ConnectionOptions? ConvertOptions(V2alpha1ConnectionStrategy? strategy, V1ConnectionOptions? source) + { + if (source is null) + return null; + + var json = JsonSerializer.SerializeToElement(source); + var options = new V2alpha1ConnectionOptions(); + + switch (strategy) + { + case V2alpha1ConnectionStrategy.Auth0: + options.Auth0 = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Ad: + options.Ad = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Adfs: + options.Adfs = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Auth0Oidc: + options.Auth0Oidc = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.AzureAd: + options.AzureAd = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Bitbucket: + options.Bitbucket = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Box: + options.Box = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Dropbox: + options.Dropbox = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Email: + options.Email = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Evernote: + options.Evernote = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.EvernoteSandbox: + options.EvernoteSandbox = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Exact: + options.Exact = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Facebook: + options.Facebook = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.GitHub: + options.GitHub = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.GoogleApps: + options.GoogleApps = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.GoogleOAuth2: + options.GoogleOAuth2 = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Linkedin: + options.Linkedin = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.OAuth1: + options.OAuth1 = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.OAuth2: + options.OAuth2 = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Office365: + options.Office365 = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Oidc: + options.Oidc = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Okta: + options.Okta = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Paypal: + options.Paypal = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.PaypalSandbox: + options.PaypalSandbox = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.PingFederate: + options.PingFederate = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Salesforce: + options.Salesforce = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.SalesforceCommunity: + options.SalesforceCommunity = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.SalesforceSandbox: + options.SalesforceSandbox = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Saml: + options.Saml = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Sms: + options.Sms = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Twitter: + options.Twitter = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.WindowsLive: + options.WindowsLive = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + case V2alpha1ConnectionStrategy.Yahoo: + options.Yahoo = V2alpha1ConnectionController.FromApi(json.Deserialize(Auth0JsonSerializerOptions)); + break; + } + + return options; + } + + static V1ConnectionOptions? RevertOptions(V2alpha1ConnectionStrategy? strategy, V2alpha1ConnectionOptions? source) + { + if (source is null) + return null; + + NormalizeSpecialSamlOptions(strategy, source); + + object? options = strategy switch + { + V2alpha1ConnectionStrategy.Auth0 => source.Auth0 is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Ad => source.Ad is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Adfs => source.Adfs is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Auth0Oidc => source.Auth0Oidc is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.AzureAd => source.AzureAd is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Bitbucket => source.Bitbucket is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Box => source.Box is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Dropbox => source.Dropbox is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Email => source.Email is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Evernote => source.Evernote is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.EvernoteSandbox => source.EvernoteSandbox is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Exact => source.Exact is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Facebook => source.Facebook is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.GitHub => source.GitHub is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.GoogleApps => source.GoogleApps is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.GoogleOAuth2 => source.GoogleOAuth2 is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Linkedin => source.Linkedin is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.OAuth1 => source.OAuth1 is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.OAuth2 => source.OAuth2 is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Office365 => source.Office365 is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Oidc => source.Oidc is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Okta => source.Okta is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Paypal => source.Paypal is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.PaypalSandbox => source.PaypalSandbox is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.PingFederate => source.PingFederate is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Salesforce => source.Salesforce is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.SalesforceCommunity => source.SalesforceCommunity is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.SalesforceSandbox => source.SalesforceSandbox is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Saml => source.Saml is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Sms => source.Sms is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Twitter => source.Twitter is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.WindowsLive => source.WindowsLive is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + V2alpha1ConnectionStrategy.Yahoo => source.Yahoo is { } v ? V2alpha1ConnectionController.ToApi(v) : null, + _ => null, + }; + + return options is not null + ? JsonSerializer.Deserialize(JsonSerializer.Serialize(options, Auth0JsonSerializerOptions)) + : null; + } + + static JsonSerializerOptions CreateAuth0JsonSerializerOptions() + { + var type = typeof(ConnectionOptionsAuth0).Assembly.GetType("Auth0.ManagementApi.Core.JsonOptions") + ?? throw new InvalidOperationException("Unable to locate Auth0.ManagementApi.Core.JsonOptions."); + + return type.GetField("JsonSerializerOptions", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)?.GetValue(null) as JsonSerializerOptions + ?? throw new InvalidOperationException("Unable to resolve Auth0 JSON serializer options."); + } + + static void NormalizeSpecialSamlOptions(V2alpha1ConnectionStrategy? strategy, V2alpha1ConnectionOptions source) + { + switch (strategy) + { + case V2alpha1ConnectionStrategy.Saml when source.Saml is { } saml: + NormalizeDecryptionKey(saml.DecryptionKey); + break; + case V2alpha1ConnectionStrategy.PingFederate when source.PingFederate is { } pingFederate: + NormalizeDecryptionKey(pingFederate.DecryptionKey); + break; + } + } + + static void NormalizeDecryptionKey(V2alpha1ConnectionDecryptionKeySaml? decryptionKey) + { + if (decryptionKey is null) + return; + + if (decryptionKey.PrivateKey is not null) + { + decryptionKey.KeyPair = null; + return; + } + + if (decryptionKey.KeyPair is not null) + { + decryptionKey.PrivateKey = null; + } + } + + } + + } + +} diff --git a/src/Alethic.Auth0.Operator/Finalizers/V1ConnectionFinalizer.cs b/src/Alethic.Auth0.Operator/Finalizers/V2alpha1ConnectionFinalizer.cs similarity index 63% rename from src/Alethic.Auth0.Operator/Finalizers/V1ConnectionFinalizer.cs rename to src/Alethic.Auth0.Operator/Finalizers/V2alpha1ConnectionFinalizer.cs index 94095f5..2927e79 100644 --- a/src/Alethic.Auth0.Operator/Finalizers/V1ConnectionFinalizer.cs +++ b/src/Alethic.Auth0.Operator/Finalizers/V2alpha1ConnectionFinalizer.cs @@ -11,22 +11,22 @@ namespace Alethic.Auth0.Operator.Finalizers { - public class V1ConnectionFinalizer : IEntityFinalizer + public class V2alpha1ConnectionFinalizer : IEntityFinalizer { - readonly IEntityController _controller; + readonly IEntityController _controller; /// /// Initializes a new instance. /// /// - public V1ConnectionFinalizer(IEntityController controller) + public V2alpha1ConnectionFinalizer(IEntityController controller) { _controller = controller ?? throw new ArgumentNullException(nameof(controller)); } /// - public async Task> FinalizeAsync(V1Connection entity, CancellationToken cancellationToken) + public async Task> FinalizeAsync(V2alpha1Connection entity, CancellationToken cancellationToken) { return await _controller.DeletedAsync(entity, cancellationToken); } diff --git a/src/Alethic.Auth0.Operator/Models/V2alpha1Client.cs b/src/Alethic.Auth0.Operator/Models/V2alpha1Client.cs new file mode 100644 index 0000000..d9d88ea --- /dev/null +++ b/src/Alethic.Auth0.Operator/Models/V2alpha1Client.cs @@ -0,0 +1,60 @@ +using System.Text.Json.Serialization; + +using Alethic.Auth0.Operator.Core.Models; +using Alethic.Auth0.Operator.Core.Models.Client.V2alpha1; + +using k8s.Models; + +using KubeOps.Abstractions.Entities; +using KubeOps.Abstractions.Entities.Attributes; + +namespace Alethic.Auth0.Operator.Models +{ + + [EntityScope(EntityScope.Namespaced)] + [KubernetesEntity(Group = "kubernetes.auth0.com", ApiVersion = "v2alpha1", Kind = "Client")] + [KubernetesEntityShortNames("a0app")] + public partial class V2alpha1Client : + CustomKubernetesEntity, + V1TenantEntityInstance + { + + public class SpecDef : V1TenantEntityInstanceSpec + { + + [JsonPropertyName("policy")] + public V1EntityPolicyType[]? Policy { get; set; } + + [JsonPropertyName("tenantRef")] + [Required] + public V1TenantReference? TenantRef { get; set; } + + [JsonPropertyName("secretRef")] + public V1SecretReference? SecretRef { get; set; } + + [JsonPropertyName("find")] + public V2alpha1ClientFind? Find { get; set; } + + [JsonPropertyName("init")] + public V2alpha1ClientConf? Init { get; set; } + + [JsonPropertyName("conf")] + [Required] + public V2alpha1ClientConf? Conf { get; set; } + + } + + public class StatusDef : V1TenantEntityInstanceStatus + { + + [JsonPropertyName("id")] + public string? Id { get; set; } + + [JsonPropertyName("lastConf")] + public V2alpha1ClientConf? LastConf { get; set; } + + } + + } + +} diff --git a/src/Alethic.Auth0.Operator/Models/V2alpha1Connection.cs b/src/Alethic.Auth0.Operator/Models/V2alpha1Connection.cs new file mode 100644 index 0000000..9391f12 --- /dev/null +++ b/src/Alethic.Auth0.Operator/Models/V2alpha1Connection.cs @@ -0,0 +1,90 @@ +using System.Text.Json.Serialization; + +using Alethic.Auth0.Operator.Core.Models; +using Alethic.Auth0.Operator.Core.Models.Connection.V2alpha1; + +using k8s.Models; + +using KubeOps.Abstractions.Entities; +using KubeOps.Abstractions.Entities.Attributes; + +namespace Alethic.Auth0.Operator.Models +{ + + [EntityScope(EntityScope.Namespaced)] + [KubernetesEntity(Group = "kubernetes.auth0.com", ApiVersion = "v2alpha1", Kind = "Connection")] + [KubernetesEntityShortNames("a0con")] + public partial class V2alpha1Connection : + CustomKubernetesEntity, + V1TenantEntityInstance + { + + public class SpecDef : V1TenantEntityInstanceSpec + { + + [JsonPropertyName("policy")] + public V1EntityPolicyType[]? Policy { get; set; } + + [JsonPropertyName("tenantRef")] + [Required] + public V1TenantReference? TenantRef { get; set; } + + [JsonPropertyName("find")] + public V2alpha1ConnectionFind? Find { get; set; } + + [JsonPropertyName("init")] + public V2alpha1ConnectionConf? Init { get; set; } + + [JsonPropertyName("conf")] + [Required] + [ValidationRule("!has(self.strategy) || self.strategy == 'auth0' ? true : !has(self.options) || !has(self.options.auth0)", "options.auth0 must only be set when strategy is 'auth0'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'ad' ? true : !has(self.options) || !has(self.options.ad)", "options.ad must only be set when strategy is 'ad'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'adfs' ? true : !has(self.options) || !has(self.options.adfs)", "options.adfs must only be set when strategy is 'adfs'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'auth0-oidc' ? true : !has(self.options) || !has(self.options.auth0Oidc)", "options.auth0Oidc must only be set when strategy is 'auth0-oidc'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'waad' ? true : !has(self.options) || !has(self.options.azureAd)", "options.azureAd must only be set when strategy is 'waad'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'bitbucket' ? true : !has(self.options) || !has(self.options.bitbucket)", "options.bitbucket must only be set when strategy is 'bitbucket'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'box' ? true : !has(self.options) || !has(self.options.box)", "options.box must only be set when strategy is 'box'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'dropbox' ? true : !has(self.options) || !has(self.options.dropbox)", "options.dropbox must only be set when strategy is 'dropbox'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'email' ? true : !has(self.options) || !has(self.options.email)", "options.email must only be set when strategy is 'email'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'evernote' ? true : !has(self.options) || !has(self.options.evernote)", "options.evernote must only be set when strategy is 'evernote'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'evernote-sandbox' ? true : !has(self.options) || !has(self.options.evernoteSandbox)", "options.evernoteSandbox must only be set when strategy is 'evernote-sandbox'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'exact' ? true : !has(self.options) || !has(self.options.exact)", "options.exact must only be set when strategy is 'exact'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'facebook' ? true : !has(self.options) || !has(self.options.facebook)", "options.facebook must only be set when strategy is 'facebook'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'github' ? true : !has(self.options) || !has(self.options.gitHub)", "options.gitHub must only be set when strategy is 'github'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'google-apps' ? true : !has(self.options) || !has(self.options.googleApps)", "options.googleApps must only be set when strategy is 'google-apps'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'google-oauth2' ? true : !has(self.options) || !has(self.options.googleOAuth2)", "options.googleOAuth2 must only be set when strategy is 'google-oauth2'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'linkedin' ? true : !has(self.options) || !has(self.options.linkedin)", "options.linkedin must only be set when strategy is 'linkedin'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'oauth1' ? true : !has(self.options) || !has(self.options.oAuth1)", "options.oAuth1 must only be set when strategy is 'oauth1'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'oauth2' ? true : !has(self.options) || !has(self.options.oAuth2)", "options.oAuth2 must only be set when strategy is 'oauth2'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'office365' ? true : !has(self.options) || !has(self.options.office365)", "options.office365 must only be set when strategy is 'office365'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'oidc' ? true : !has(self.options) || !has(self.options.oidc)", "options.oidc must only be set when strategy is 'oidc'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'okta' ? true : !has(self.options) || !has(self.options.okta)", "options.okta must only be set when strategy is 'okta'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'paypal' ? true : !has(self.options) || !has(self.options.paypal)", "options.paypal must only be set when strategy is 'paypal'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'paypal-sandbox' ? true : !has(self.options) || !has(self.options.paypalSandbox)", "options.paypalSandbox must only be set when strategy is 'paypal-sandbox'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'pingfederate' ? true : !has(self.options) || !has(self.options.pingFederate)", "options.pingFederate must only be set when strategy is 'pingfederate'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'salesforce' ? true : !has(self.options) || !has(self.options.salesforce)", "options.salesforce must only be set when strategy is 'salesforce'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'salesforce-community' ? true : !has(self.options) || !has(self.options.salesforceCommunity)", "options.salesforceCommunity must only be set when strategy is 'salesforce-community'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'salesforce-sandbox' ? true : !has(self.options) || !has(self.options.salesforceSandbox)", "options.salesforceSandbox must only be set when strategy is 'salesforce-sandbox'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'samlp' ? true : !has(self.options) || !has(self.options.saml)", "options.saml must only be set when strategy is 'samlp'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'sms' ? true : !has(self.options) || !has(self.options.sms)", "options.sms must only be set when strategy is 'sms'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'twitter' ? true : !has(self.options) || !has(self.options.twitter)", "options.twitter must only be set when strategy is 'twitter'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'windowslive' ? true : !has(self.options) || !has(self.options.windowsLive)", "options.windowsLive must only be set when strategy is 'windowslive'")] + [ValidationRule("!has(self.strategy) || self.strategy == 'yahoo' ? true : !has(self.options) || !has(self.options.yahoo)", "options.yahoo must only be set when strategy is 'yahoo'")] + public V2alpha1ConnectionConf? Conf { get; set; } + + } + + public class StatusDef : V1TenantEntityInstanceStatus + { + + [JsonPropertyName("id")] + public string? Id { get; set; } + + [JsonPropertyName("lastConf")] + public V2alpha1ConnectionConf? LastConf { get; set; } + + } + + } + +}