Fix external authentication setting field identifiers

This commit is contained in:
Sipke Schoorstra 2026-07-25 14:07:06 +02:00
parent b402d4da8f
commit f1e2a092f9
No known key found for this signature in database
GPG key ID: 5C10502B28A4268F
2 changed files with 23 additions and 1 deletions

View file

@ -10,6 +10,7 @@ namespace Elsa.ExternalAuthentication.Services;
public sealed class ExtensionDescriptorValidator
{
private static readonly Regex IdentifierPattern = new("^[a-z][a-z0-9]*(?:[-.][a-z0-9]+)*$", RegexOptions.CultureInvariant);
private static readonly Regex SettingFieldNamePattern = new("^[a-z][A-Za-z0-9]*$", RegexOptions.CultureInvariant);
private static readonly HashSet<string> SupportedValueTypes = new(StringComparer.Ordinal)
{
"string", "secret", "boolean", "integer", "number", "uri", "string-array", "json"
@ -79,7 +80,7 @@ public sealed class ExtensionDescriptorValidator
var names = new HashSet<string>(StringComparer.Ordinal);
foreach (var field in fields)
{
if (!IsIdentifier(field.Name))
if (!IsSettingFieldName(field.Name))
failures.Add($"Extension '{extensionType}' has invalid field name '{field.Name}'.");
else if (!names.Add(field.Name))
failures.Add($"Extension '{extensionType}' defines field '{field.Name}' more than once.");
@ -123,4 +124,7 @@ public sealed class ExtensionDescriptorValidator
private static bool IsIdentifier(string? value) =>
!string.IsNullOrWhiteSpace(value) && IdentifierPattern.IsMatch(value);
private static bool IsSettingFieldName(string? value) =>
!string.IsNullOrWhiteSpace(value) && SettingFieldNamePattern.IsMatch(value);
}

View file

@ -2,6 +2,7 @@ using System.Text.Json;
using Elsa.ExternalAuthentication.Contracts;
using Elsa.ExternalAuthentication.Models;
using Elsa.ExternalAuthentication.Options;
using Elsa.ExternalAuthentication.Policies;
using Elsa.ExternalAuthentication.Services;
namespace Elsa.ExternalAuthentication.UnitTests.Extensibility;
@ -80,6 +81,23 @@ public class ExtensionConformanceTests
Assert.Contains("custom-editor", exception.Message);
}
[Fact]
public void DescriptorValidatorAcceptsLowerCamelCaseSettingFieldNames()
{
var descriptor = new ExtensionDescriptorValidator().Validate(new CreateUserUnlinkedIdentityPolicy());
Assert.Contains(descriptor.Fields, field => field.Name == "defaultRoleIds");
}
[Fact]
public void DescriptorValidatorKeepsExtensionTypesLowercaseAndStable()
{
var exception = Assert.Throws<InvalidOperationException>(() =>
new ExtensionDescriptorValidator().Validate(new ConformanceAdapter("InvalidType")));
Assert.Contains("stable identifier", exception.Message);
}
[Fact]
public async Task SettingsMigrationRunsAdapterOwnedForwardStepsAndRejectsUnsupportedVersions()
{