From 4bdea63982dae9c17b7a5fbda38d505655b8d4b3 Mon Sep 17 00:00:00 2001 From: "Emma [it/its]@Rory&" Date: Thu, 30 May 2024 21:39:12 +0200 Subject: Changes --- .../JsonElementExtensions.cs | 147 +++++++++++++++++++++ .../LibMatrix.DebugDataValidationApi.csproj | 4 +- .../Bot/FileStorageProvider.cs | 72 +++++----- .../LibMatrix.Utilities.Bot/FileStorageProvider.cs | 64 ++++----- .../LibMatrix.Utilities.Bot.csproj | 4 +- 5 files changed, 219 insertions(+), 72 deletions(-) create mode 100644 Utilities/LibMatrix.DebugDataValidationApi/JsonElementExtensions.cs (limited to 'Utilities') diff --git a/Utilities/LibMatrix.DebugDataValidationApi/JsonElementExtensions.cs b/Utilities/LibMatrix.DebugDataValidationApi/JsonElementExtensions.cs new file mode 100644 index 0000000..c4ed743 --- /dev/null +++ b/Utilities/LibMatrix.DebugDataValidationApi/JsonElementExtensions.cs @@ -0,0 +1,147 @@ +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization; + +namespace LibMatrix.Extensions; + +public static class JsonElementExtensions { + public static bool FindExtraJsonElementFields(this JsonElement obj, Type objectType, string objectPropertyName) { + if (objectPropertyName == "content" && objectType == typeof(JsonObject)) + objectType = typeof(StateEventResponse); + // if (t == typeof(JsonNode)) + // return false; + + Console.WriteLine($"{objectType.Name} {objectPropertyName}"); + var unknownPropertyFound = false; + var mappedPropsDict = objectType.GetProperties() + .Where(x => x.GetCustomAttribute() is not null) + .ToDictionary(x => x.GetCustomAttribute()!.Name, x => x); + objectType.GetProperties().Where(x => !mappedPropsDict.ContainsKey(x.Name)) + .ToList().ForEach(x => mappedPropsDict.TryAdd(x.Name, x)); + + foreach (var field in obj.EnumerateObject()) { + if (mappedPropsDict.TryGetValue(field.Name, out var mappedProperty)) { + //dictionary + if (mappedProperty.PropertyType.IsGenericType && + mappedProperty.PropertyType.GetGenericTypeDefinition() == typeof(Dictionary<,>)) { + unknownPropertyFound |= _checkDictionary(field, objectType, mappedProperty.PropertyType); + continue; + } + + if (mappedProperty.PropertyType.IsGenericType && + mappedProperty.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) { + unknownPropertyFound |= _checkList(field, objectType, mappedProperty.PropertyType); + continue; + } + + if (field.Name == "content" && (objectType == typeof(StateEventResponse) || objectType == typeof(StateEvent))) { + unknownPropertyFound |= field.FindExtraJsonPropertyFieldsByValueKind( + StateEvent.GetStateEventType(obj.GetProperty("type").GetString()!), // We expect type to always be present + mappedProperty.PropertyType); + continue; + } + + unknownPropertyFound |= + field.FindExtraJsonPropertyFieldsByValueKind(objectType, mappedProperty.PropertyType); + continue; + } + + Console.WriteLine($"[!!] Unknown property {field.Name} in {objectType.Name}!"); + unknownPropertyFound = true; + } + + return unknownPropertyFound; + } + + private static bool FindExtraJsonPropertyFieldsByValueKind(this JsonProperty field, Type containerType, + Type propertyType) { + if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) propertyType = propertyType.GetGenericArguments()[0]; + + var switchResult = false; + switch (field.Value.ValueKind) { + case JsonValueKind.Array: + switchResult = field.Value.EnumerateArray().Aggregate(switchResult, + (current, element) => current | element.FindExtraJsonElementFields(propertyType, field.Name)); + break; + case JsonValueKind.Object: + switchResult |= field.Value.FindExtraJsonElementFields(propertyType, field.Name); + break; + case JsonValueKind.True: + case JsonValueKind.False: + return _checkBool(field, containerType, propertyType); + case JsonValueKind.String: + return _checkString(field, containerType, propertyType); + case JsonValueKind.Number: + return _checkNumber(field, containerType, propertyType); + case JsonValueKind.Undefined: + case JsonValueKind.Null: + break; + default: + throw new ArgumentOutOfRangeException(); + } + + return switchResult; + } + + private static bool _checkBool(this JsonProperty field, Type containerType, Type propertyType) { + if (propertyType == typeof(bool)) return true; + Console.WriteLine( + $"[!!] Encountered bool for {field.Name} in {containerType.Name}, the class defines {propertyType.Name}!"); + return false; + } + + private static bool _checkString(this JsonProperty field, Type containerType, Type propertyType) { + if (propertyType == typeof(string)) return true; + // ReSharper disable once BuiltInTypeReferenceStyle + if (propertyType == typeof(String)) return true; + Console.WriteLine( + $"[!!] Encountered string for {field.Name} in {containerType.Name}, the class defines {propertyType.Name}!"); + return false; + } + + private static bool _checkNumber(this JsonProperty field, Type containerType, Type propertyType) { + if (propertyType == typeof(int) || + propertyType == typeof(double) || + propertyType == typeof(float) || + propertyType == typeof(decimal) || + propertyType == typeof(long) || + propertyType == typeof(short) || + propertyType == typeof(uint) || + propertyType == typeof(ulong) || + propertyType == typeof(ushort) || + propertyType == typeof(byte) || + propertyType == typeof(sbyte)) + return true; + Console.WriteLine( + $"[!!] Encountered number for {field.Name} in {containerType.Name}, the class defines {propertyType.Name}!"); + return false; + } + + private static bool _checkDictionary(this JsonProperty field, Type containerType, Type propertyType) { + var keyType = propertyType.GetGenericArguments()[0]; + var valueType = propertyType.GetGenericArguments()[1]; + valueType = Nullable.GetUnderlyingType(valueType) ?? valueType; + Console.WriteLine( + $"Encountered dictionary {field.Name} with key type {keyType.Name} and value type {valueType.Name}!"); + + return field.Value.EnumerateObject() + .Where(key => !valueType.IsPrimitive && valueType != typeof(string)) + .Aggregate(false, (current, key) => + current | key.FindExtraJsonPropertyFieldsByValueKind(containerType, valueType) + ); + } + + private static bool _checkList(this JsonProperty field, Type containerType, Type propertyType) { + var valueType = propertyType.GetGenericArguments()[0]; + valueType = Nullable.GetUnderlyingType(valueType) ?? valueType; + Console.WriteLine( + $"Encountered list {field.Name} with value type {valueType.Name}!"); + + return field.Value.EnumerateArray() + .Where(key => !valueType.IsPrimitive && valueType != typeof(string)) + .Aggregate(false, (current, key) => + current | key.FindExtraJsonElementFields(valueType, field.Name) + ); + } +} \ No newline at end of file diff --git a/Utilities/LibMatrix.DebugDataValidationApi/LibMatrix.DebugDataValidationApi.csproj b/Utilities/LibMatrix.DebugDataValidationApi/LibMatrix.DebugDataValidationApi.csproj index 24fd617..3466fb1 100644 --- a/Utilities/LibMatrix.DebugDataValidationApi/LibMatrix.DebugDataValidationApi.csproj +++ b/Utilities/LibMatrix.DebugDataValidationApi/LibMatrix.DebugDataValidationApi.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/Utilities/LibMatrix.DevTestBot/Bot/FileStorageProvider.cs b/Utilities/LibMatrix.DevTestBot/Bot/FileStorageProvider.cs index cc866e6..05b357e 100644 --- a/Utilities/LibMatrix.DevTestBot/Bot/FileStorageProvider.cs +++ b/Utilities/LibMatrix.DevTestBot/Bot/FileStorageProvider.cs @@ -1,36 +1,36 @@ -using System.Text.Json; -using ArcaneLibs.Extensions; -using LibMatrix.Interfaces.Services; -using Microsoft.Extensions.Logging; - -namespace LibMatrix.ExampleBot.Bot; - -public class FileStorageProvider : IStorageProvider { - private readonly ILogger _logger; - - public string TargetPath { get; } - - /// - /// Creates a new instance of . - /// - /// - public FileStorageProvider(string targetPath) { - new Logger(new LoggerFactory()).LogInformation("test"); - Console.WriteLine($"Initialised FileStorageProvider with path {targetPath}"); - TargetPath = targetPath; - if (!Directory.Exists(targetPath)) Directory.CreateDirectory(targetPath); - } - - public async Task SaveObjectAsync(string key, T value) => await File.WriteAllTextAsync(Path.Join(TargetPath, key), value?.ToJson()); - - public async Task LoadObjectAsync(string key) => JsonSerializer.Deserialize(await File.ReadAllTextAsync(Path.Join(TargetPath, key))); - - public Task ObjectExistsAsync(string key) => Task.FromResult(File.Exists(Path.Join(TargetPath, key))); - - public Task> GetAllKeysAsync() => Task.FromResult(Directory.GetFiles(TargetPath).Select(Path.GetFileName).ToList()); - - public Task DeleteObjectAsync(string key) { - File.Delete(Path.Join(TargetPath, key)); - return Task.CompletedTask; - } -} \ No newline at end of file +// using System.Text.Json; +// using ArcaneLibs.Extensions; +// using LibMatrix.Interfaces.Services; +// using Microsoft.Extensions.Logging; +// +// namespace LibMatrix.ExampleBot.Bot; +// +// public class FileStorageProvider : IStorageProvider { +// private readonly ILogger _logger; +// +// public string TargetPath { get; } +// +// /// +// /// Creates a new instance of . +// /// +// /// +// public FileStorageProvider(string targetPath) { +// new Logger(new LoggerFactory()).LogInformation("test"); +// Console.WriteLine($"Initialised FileStorageProvider with path {targetPath}"); +// TargetPath = targetPath; +// if (!Directory.Exists(targetPath)) Directory.CreateDirectory(targetPath); +// } +// +// public async Task SaveObjectAsync(string key, T value) => await File.WriteAllTextAsync(Path.Join(TargetPath, key), value?.ToJson()); +// +// public async Task LoadObjectAsync(string key) => JsonSerializer.Deserialize(await File.ReadAllTextAsync(Path.Join(TargetPath, key))); +// +// public Task ObjectExistsAsync(string key) => Task.FromResult(File.Exists(Path.Join(TargetPath, key))); +// +// public Task> GetAllKeysAsync() => Task.FromResult(Directory.GetFiles(TargetPath).Select(Path.GetFileName).ToList()); +// +// public Task DeleteObjectAsync(string key) { +// File.Delete(Path.Join(TargetPath, key)); +// return Task.CompletedTask; +// } +// } \ No newline at end of file diff --git a/Utilities/LibMatrix.Utilities.Bot/FileStorageProvider.cs b/Utilities/LibMatrix.Utilities.Bot/FileStorageProvider.cs index b762937..f723c57 100644 --- a/Utilities/LibMatrix.Utilities.Bot/FileStorageProvider.cs +++ b/Utilities/LibMatrix.Utilities.Bot/FileStorageProvider.cs @@ -1,32 +1,32 @@ -using System.Text.Json; -using ArcaneLibs.Extensions; -using LibMatrix.Interfaces.Services; - -namespace LibMatrix.Utilities.Bot; - -public class FileStorageProvider : IStorageProvider { - public string TargetPath { get; } - - /// - /// Creates a new instance of . - /// - /// - public FileStorageProvider(string targetPath) { - Console.WriteLine($"Initialised FileStorageProvider with path {targetPath}"); - TargetPath = targetPath; - if (!Directory.Exists(targetPath)) Directory.CreateDirectory(targetPath); - } - - public async Task SaveObjectAsync(string key, T value) => await File.WriteAllTextAsync(Path.Join(TargetPath, key), value?.ToJson()); - - public async Task LoadObjectAsync(string key) => JsonSerializer.Deserialize(await File.ReadAllTextAsync(Path.Join(TargetPath, key))); - - public Task ObjectExistsAsync(string key) => Task.FromResult(File.Exists(Path.Join(TargetPath, key))); - - public Task> GetAllKeysAsync() => Task.FromResult(Directory.GetFiles(TargetPath).Select(Path.GetFileName).ToList()); - - public Task DeleteObjectAsync(string key) { - File.Delete(Path.Join(TargetPath, key)); - return Task.CompletedTask; - } -} \ No newline at end of file +// using System.Text.Json; +// using ArcaneLibs.Extensions; +// using LibMatrix.Interfaces.Services; +// +// namespace LibMatrix.Utilities.Bot; +// +// public class FileStorageProvider : IStorageProvider { +// public string TargetPath { get; } +// +// /// +// /// Creates a new instance of . +// /// +// /// +// public FileStorageProvider(string targetPath) { +// Console.WriteLine($"Initialised FileStorageProvider with path {targetPath}"); +// TargetPath = targetPath; +// if (!Directory.Exists(targetPath)) Directory.CreateDirectory(targetPath); +// } +// +// public async Task SaveObjectAsync(string key, T value) => await File.WriteAllTextAsync(Path.Join(TargetPath, key), value?.ToJson()); +// +// public async Task LoadObjectAsync(string key) => JsonSerializer.Deserialize(await File.ReadAllTextAsync(Path.Join(TargetPath, key))); +// +// public Task ObjectExistsAsync(string key) => Task.FromResult(File.Exists(Path.Join(TargetPath, key))); +// +// public Task> GetAllKeysAsync() => Task.FromResult(Directory.GetFiles(TargetPath).Select(Path.GetFileName).ToList()); +// +// public Task DeleteObjectAsync(string key) { +// File.Delete(Path.Join(TargetPath, key)); +// return Task.CompletedTask; +// } +// } \ No newline at end of file diff --git a/Utilities/LibMatrix.Utilities.Bot/LibMatrix.Utilities.Bot.csproj b/Utilities/LibMatrix.Utilities.Bot/LibMatrix.Utilities.Bot.csproj index 89ea5af..6e67373 100644 --- a/Utilities/LibMatrix.Utilities.Bot/LibMatrix.Utilities.Bot.csproj +++ b/Utilities/LibMatrix.Utilities.Bot/LibMatrix.Utilities.Bot.csproj @@ -12,9 +12,9 @@ - + - + -- cgit 1.4.1