Skip to content

Commit

Permalink
fix: OR-2035 recursively apply validation rules for requests and inva…
Browse files Browse the repository at this point in the history
…lidate html fields
  • Loading branch information
Jan Lesage committed Jan 10, 2024
1 parent 3dc5a42 commit a94e864
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
namespace AssociationRegistry.Admin.Api.Infrastructure.Extensions;

using ExceptionHandlers;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using FluentValidation;
using HtmlValidation;
using System.Linq;
using JasperFx.Core.Reflection;
using Microsoft.AspNetCore.Http;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

public static class FluentValidatorExtensions
{
Expand All @@ -18,40 +21,72 @@ public static async Task NullValidateAndThrowAsync<T>(
{
if (instance is null) throw new CouldNotParseRequestException();

await new NoHtmlValidator<T>().ValidateAndThrowAsync(instance, cancellationToken: cancellationToken);
await new NoHtmlValidator<T>().ValidateAndThrowAsync(instance, cancellationToken);
await validator.ValidateAndThrowAsync(instance, cancellationToken);
}
}

public class NoHtmlValidator<T> : AbstractValidator<T>
{
private const string TO_BE_STRIPPED_PREFIX = "to-be-stripped-request-prefix";

public NoHtmlValidator()
{
// TODO: nested
// TODO: es kijken naar 'I <3 <Programming>' als waarde?
var propertiesWithNoHtml = typeof(T).GetProperties()
.Where(p => p.GetCustomAttributes(typeof(NoHtmlAttribute), false).Any());
RecursivelyApplyRule(typeof(T), TO_BE_STRIPPED_PREFIX);
}

private void RecursivelyApplyRule(Type type, string propertyName)
{
var props = type.GetProperties();

foreach (var property in propertiesWithNoHtml)
foreach (var prop in props)
{
if (property.PropertyType == typeof(string))
var currentPropertyName = $"{propertyName}.{prop.Name}";

if (prop.HasAttribute<NoHtmlAttribute>())
{
ApplyRuleFor(prop, currentPropertyName);
}
else if (prop.PropertyType.IsArray)
{
RuleFor(model => GetPropertyValue(model, property.Name) as string)
.Must(BeNoHtml!)
.WithMessage(ExceptionMessages.UnsupportedContent)
.When(model => GetPropertyValue(model, property.Name) != null);
if (prop.PropertyType.IsClass)
RecursivelyApplyRule(prop.PropertyType, currentPropertyName);
else
ApplyRuleForEach(prop, currentPropertyName);
}
else if (property.PropertyType == typeof(string[]))
else if (prop.PropertyType.IsClass)
{
RuleForEach(model => GetPropertyValue(model, property.Name) as string[])
.Must(BeNoHtml!)
.WithName(property.Name)
.WithMessage(ExceptionMessages.UnsupportedContent)
.When(model => GetPropertyValue(model, property.Name) != null);
RecursivelyApplyRule(prop.PropertyType, currentPropertyName);
}
}
}

private void ApplyRuleFor(PropertyInfo prop, string propertyName)
{
if (prop.PropertyType == typeof(string))
RuleFor(model => GetPropertyValue(model, prop.Name) as string)
.Cascade(CascadeMode.Continue)
.Must(BeNoHtml!)
.WithName(propertyName.Replace($"{TO_BE_STRIPPED_PREFIX}.", newValue: ""))
.WithErrorCode(StatusCodes.Status400BadRequest.ToString())
.WithMessage(ExceptionMessages.UnsupportedContent)
.When(model => GetPropertyValue(model, prop.Name) != null);
}

private void ApplyRuleForEach(PropertyInfo prop, string propertyName)
{
if (prop.PropertyType == typeof(string[]))
RuleForEach(model => Convert.ChangeType(GetPropertyValue(model, prop.Name), prop.PropertyType) as string[])
.Cascade(CascadeMode.Continue)
.Must(BeNoHtml!)
.WithName(propertyName.Replace($"{TO_BE_STRIPPED_PREFIX}.", newValue: ""))
.WithErrorCode(StatusCodes.Status400BadRequest.ToString())
.WithMessage(ExceptionMessages.UnsupportedContent)
.When(model => GetPropertyValue(model, prop.Name) != null);
}

private static object? GetPropertyValue(T model, string propertyName)
{
var property = typeof(T).GetProperty(propertyName);
Expand All @@ -60,5 +95,5 @@ public NoHtmlValidator()
}

private static bool BeNoHtml(string propertyValue)
=> !Regex.IsMatch(propertyValue, "<.*?>");
=> !Regex.IsMatch(propertyValue, pattern: "<.*?>");
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,25 @@ public IEnumerator<object[]> GetEnumerator()
var autoFixture = new Fixture().CustomizeAdminApi();

var request1 = autoFixture.Create<RegistreerFeitelijkeVerenigingRequest>();
request1.Naam = $"<h1>{autoFixture.Create<string>()}</h1>";

// request1.Naam = $"<h1>{autoFixture.Create<string>()}</h1>";
request1.Contactgegevens = new ToeTeVoegenContactgegeven[]
{
new()
{
Beschrijving = $"<h2>{autoFixture.Create<string>()}</h2>",
Contactgegeventype = "Mumbo Jumbo",
Waarde = "<span>Test</span>",
IsPrimair = false,
},
new()
{
Beschrijving = $"<h2>{autoFixture.Create<string>()}</h2>",
Contactgegeventype = $"<h3>{autoFixture.Create<string>()}</h3>",
Waarde = "Test",
IsPrimair = false,
},
};

yield return new object[] { request1 };

Expand Down

0 comments on commit a94e864

Please sign in to comment.