-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from bsandmann/dev
Dev
- Loading branch information
Showing
19 changed files
with
2,134 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
...ialWorkflow.Core/Commands/ValidateCredentials/CustomValidation/CustomValidationHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using System.Text.Json; | ||
using FluentResults; | ||
using Jint; | ||
using MediatR; | ||
|
||
namespace Blocktrust.CredentialWorkflow.Core.Commands.ValidateCredentials.CustomValidation; | ||
|
||
public class CustomValidationHandler : IRequestHandler<CustomValidationRequest, Result<CustomValidationResult>> | ||
{ | ||
public async Task<Result<CustomValidationResult>> Handle(CustomValidationRequest request, CancellationToken cancellationToken) | ||
{ | ||
var result = new CustomValidationResult(); | ||
var engine = new Engine(); | ||
|
||
try | ||
{ | ||
// Convert data to JSON string for JavaScript engine | ||
var dataJson = JsonSerializer.Serialize(request.Data); | ||
|
||
// Set up the JavaScript environment | ||
engine.SetValue("data", JsonSerializer.Deserialize<JsonElement>(dataJson)); | ||
|
||
foreach (var rule in request.Rules) | ||
{ | ||
try | ||
{ | ||
// Execute each validation rule | ||
var isValid = engine.Evaluate(rule.Expression).AsBoolean(); | ||
|
||
if (!isValid) | ||
{ | ||
result.Errors.Add(new CustomValidationError( | ||
rule.Name, | ||
rule.ErrorMessage ?? $"Validation rule '{rule.Name}' failed" | ||
)); | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
result.Errors.Add(new CustomValidationError( | ||
rule.Name, | ||
$"Error evaluating rule: {ex.Message}" | ||
)); | ||
} | ||
} | ||
|
||
result.IsValid = !result.Errors.Any(); | ||
return Result.Ok(result); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return Result.Fail($"Validation failed: {ex.Message}"); | ||
} | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
...ialWorkflow.Core/Commands/ValidateCredentials/CustomValidation/CustomValidationRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using Blocktrust.CredentialWorkflow.Core.Domain.ProcessFlow.Actions.Validation; | ||
using FluentResults; | ||
using MediatR; | ||
|
||
namespace Blocktrust.CredentialWorkflow.Core.Commands.ValidateCredentials.CustomValidation; | ||
|
||
public class CustomValidationRequest : IRequest<Result<CustomValidationResult>> | ||
{ | ||
public object Data { get; } | ||
public List<CustomValidationRule> Rules { get; } | ||
|
||
public CustomValidationRequest(object data, List<CustomValidationRule> rules) | ||
{ | ||
Data = data; | ||
Rules = rules; | ||
} | ||
} | ||
|
||
public class CustomValidationResult | ||
{ | ||
public bool IsValid { get; set; } | ||
public List<CustomValidationError> Errors { get; set; } = new(); | ||
} | ||
|
||
public class CustomValidationError | ||
{ | ||
public string RuleName { get; set; } | ||
public string Message { get; set; } | ||
|
||
public CustomValidationError(string ruleName, string message) | ||
{ | ||
RuleName = ruleName; | ||
Message = message; | ||
} | ||
} |
157 changes: 157 additions & 0 deletions
157
...redentialWorkflow.Core/Commands/ValidateCredentials/W3cValidation/W3cValidationHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
using System.Text.Json; | ||
using Blocktrust.CredentialWorkflow.Core.Domain.ProcessFlow.Actions.Validation; | ||
using FluentResults; | ||
using MediatR; | ||
|
||
namespace Blocktrust.CredentialWorkflow.Core.Commands.ValidateCredentials.W3cValidation; | ||
|
||
public class W3cValidationHandler : IRequestHandler<W3cValidationRequest, Result<ValidationResult>> | ||
{ | ||
public async Task<Result<ValidationResult>> Handle(W3cValidationRequest request, CancellationToken cancellationToken) | ||
{ | ||
var result = new ValidationResult(); | ||
try | ||
{ | ||
var credentialJson = JsonDocument.Parse(request.Credential); | ||
|
||
foreach (var rule in request.Rules) | ||
{ | ||
switch (rule.Type.ToLower()) | ||
{ | ||
case "required": | ||
ValidateRequiredField(credentialJson, rule, result); | ||
break; | ||
case "format": | ||
ValidateFormat(credentialJson, rule, result); | ||
break; | ||
case "range": | ||
ValidateRange(credentialJson, rule, result); | ||
break; | ||
case "custom": | ||
ValidateCustomRule(credentialJson, rule, result); | ||
break; | ||
} | ||
} | ||
|
||
result.IsValid = !result.Errors.Any(); | ||
return Result.Ok(result); | ||
} | ||
catch (JsonException ex) | ||
{ | ||
return Result.Fail($"Invalid credential format: {ex.Message}"); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return Result.Fail($"Validation failed: {ex.Message}"); | ||
} | ||
} | ||
|
||
private void ValidateRequiredField(JsonDocument credential, ValidationRule rule, ValidationResult result) | ||
{ | ||
var path = rule.Configuration; | ||
var pathParts = path.Split('.'); | ||
var element = credential.RootElement; | ||
|
||
foreach (var part in pathParts) | ||
{ | ||
if (!element.TryGetProperty(part, out var child)) | ||
{ | ||
result.Errors.Add(new ValidationError("Required", $"Required field '{path}' is missing")); | ||
return; | ||
} | ||
element = child; | ||
} | ||
} | ||
|
||
private void ValidateFormat(JsonDocument credential, ValidationRule rule, ValidationResult result) | ||
{ | ||
var config = rule.Configuration.Split(':'); | ||
if (config.Length != 2) | ||
{ | ||
result.Errors.Add(new ValidationError("Format", "Invalid format rule configuration")); | ||
return; | ||
} | ||
|
||
var path = config[0]; | ||
var format = config[1]; | ||
var pathParts = path.Split('.'); | ||
var element = credential.RootElement; | ||
|
||
foreach (var part in pathParts) | ||
{ | ||
if (!element.TryGetProperty(part, out var child)) | ||
{ | ||
result.Errors.Add(new ValidationError("Format", $"Field '{path}' not found")); | ||
return; | ||
} | ||
element = child; | ||
} | ||
|
||
// Validate format based on the format type | ||
switch (format.ToUpper()) | ||
{ | ||
case "ISO8601": | ||
if (!DateTime.TryParse(element.GetString(), out _)) | ||
{ | ||
result.Errors.Add(new ValidationError("Format", $"Field '{path}' is not a valid ISO8601 date")); | ||
} | ||
break; | ||
// Add more format validations as needed | ||
} | ||
} | ||
|
||
private void ValidateRange(JsonDocument credential, ValidationRule rule, ValidationResult result) | ||
{ | ||
var config = rule.Configuration.Split(':'); | ||
if (config.Length != 2) | ||
{ | ||
result.Errors.Add(new ValidationError("Range", "Invalid range rule configuration")); | ||
return; | ||
} | ||
|
||
var path = config[0]; | ||
var range = config[1].Split('-'); | ||
if (range.Length != 2) | ||
{ | ||
result.Errors.Add(new ValidationError("Range", "Invalid range format")); | ||
return; | ||
} | ||
|
||
if (!decimal.TryParse(range[0], out var min) || !decimal.TryParse(range[1], out var max)) | ||
{ | ||
result.Errors.Add(new ValidationError("Range", "Invalid range values")); | ||
return; | ||
} | ||
|
||
var pathParts = path.Split('.'); | ||
var element = credential.RootElement; | ||
|
||
foreach (var part in pathParts) | ||
{ | ||
if (!element.TryGetProperty(part, out var child)) | ||
{ | ||
result.Errors.Add(new ValidationError("Range", $"Field '{path}' not found")); | ||
return; | ||
} | ||
element = child; | ||
} | ||
|
||
if (!decimal.TryParse(element.GetString(), out var value)) | ||
{ | ||
result.Errors.Add(new ValidationError("Range", $"Field '{path}' is not a valid number")); | ||
return; | ||
} | ||
|
||
if (value < min || value > max) | ||
{ | ||
result.Errors.Add(new ValidationError("Range", $"Field '{path}' value {value} is outside range {min}-{max}")); | ||
} | ||
} | ||
|
||
private void ValidateCustomRule(JsonDocument credential, ValidationRule rule, ValidationResult result) | ||
{ | ||
// Custom rule validation - can be extended based on requirements | ||
// For now, just log that custom validation is not implemented | ||
result.Errors.Add(new ValidationError("Custom", "Custom validation rules are not implemented")); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
...redentialWorkflow.Core/Commands/ValidateCredentials/W3cValidation/W3cValidationRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using Blocktrust.CredentialWorkflow.Core.Domain.ProcessFlow.Actions.Validation; | ||
using FluentResults; | ||
using MediatR; | ||
|
||
namespace Blocktrust.CredentialWorkflow.Core.Commands.ValidateCredentials.W3cValidation; | ||
|
||
public class W3cValidationRequest : IRequest<Result<ValidationResult>> | ||
{ | ||
public string Credential { get; } | ||
public List<ValidationRule> Rules { get; } | ||
|
||
public W3cValidationRequest(string credential, List<ValidationRule> rules) | ||
{ | ||
Credential = credential; | ||
Rules = rules; | ||
} | ||
} | ||
|
||
public class ValidationResult | ||
{ | ||
public bool IsValid { get; set; } | ||
public List<ValidationError> Errors { get; set; } = new(); | ||
} | ||
|
||
public class ValidationError | ||
{ | ||
public string RuleType { get; set; } | ||
public string Message { get; set; } | ||
|
||
public ValidationError(string ruleType, string message) | ||
{ | ||
RuleType = ruleType; | ||
Message = message; | ||
} | ||
} |
Oops, something went wrong.