-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New validation and partial validation via PATCH endpoint #393
Conversation
Improve GetJsonPath(Expression) and fix some sonarcloud issues Improve test coverage Full validation rewrite complete and existing tests work Probably still some issues and test coverage was spoty so more tests needs to be written. Make IInstanceValidator obsolete Add DataType as input to validators Fix a few issues to prepare for tests of expressions Add more tests
Also comment out KeyedService fetching
709d48c
to
8636355
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
411bce5
to
88fc96d
Compare
…versions, this label can also be an expression, so parsing fails when this is expected to be a string.
…ts. Frontend doesn't use this anymore, and disallows rendering Summary components with it.
Improve handeling of errors in PATCH endpoint code style fixes
9da5903
to
ebcb89a
Compare
9b84ada
to
9ebe588
Compare
xml serializing does always preserve empty string when using attributes and [XmlText].
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some initial comments. Haven't looked at the test code yet, but wanted to get the first src comments out the door
src/Altinn.App.Core/Internal/Expressions/LayoutEvaluatorState.cs
Outdated
Show resolved
Hide resolved
src/Altinn.App.Core/Features/Validation/Default/DataAnnotationValidator.cs
Show resolved
Hide resolved
Co-authored-by: Vemund Gaukstad <[email protected]>
fix style issues
99ef9a3
to
00e3be8
Compare
} | ||
catch (Exception e) | ||
{ | ||
_logger.LogError(e, "Error while running validator {validatorName} on task {taskId} in instance {instanceId}", tv.GetType().Name, taskId, instance.Id); |
Check failure
Code scanning / CodeQL
Log entries created from user input High
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
} | ||
catch (Exception e) | ||
{ | ||
_logger.LogError(e, "Error while running validator {validatorName} on task {taskId} in instance {instanceId}", tv.GetType().Name, taskId, instance.Id); |
Check failure
Code scanning / CodeQL
Log entries created from user input High
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
{ | ||
try | ||
{ | ||
_logger.LogDebug("Start running validator {validatorName} on task {taskId} in instance {instanceId}", tv.GetType().Name, taskId, instance.Id); |
Check failure
Code scanning / CodeQL
Log entries created from user input High
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
{ | ||
try | ||
{ | ||
_logger.LogDebug("Start running validator {validatorName} on task {taskId} in instance {instanceId}", tv.GetType().Name, taskId, instance.Id); |
Check failure
Code scanning / CodeQL
Log entries created from user input High
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
} | ||
catch (Exception e) | ||
{ | ||
_logger.LogError(e, "Error while running validator {validatorName} on {dataType} for data element {dataElementId} in instance {instanceId}", v.GetType().Name, dataElement.DataType, dataElement.Id, instance.Id); |
Check failure
Code scanning / CodeQL
Log entries created from user input High
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
} | ||
catch (Exception e) | ||
{ | ||
_logger.LogError(e, "Error while running validator {validatorName} on {dataType} for data element {dataElementId} in instance {instanceId}", v.GetType().Name, dataElement.DataType, dataElement.Id, instance.Id); |
Check failure
Code scanning / CodeQL
Log entries created from user input High
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
{ | ||
try | ||
{ | ||
_logger.LogDebug("Start running validator {validatorName} on {dataType} for data element {dataElementId} in instance {instanceId}", v.GetType().Name, dataElement.DataType, dataElement.Id, instance.Id); |
Check failure
Code scanning / CodeQL
Log entries created from user input High
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
{ | ||
try | ||
{ | ||
_logger.LogDebug("Start running validator {validatorName} on {dataType} for data element {dataElementId} in instance {instanceId}", v.GetType().Name, dataElement.DataType, dataElement.Id, instance.Id); |
Check failure
Code scanning / CodeQL
Log entries created from user input High
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
This log entry depends on a
user-provided value
catch (Exception e) | ||
{ | ||
return Task.FromException<List<ValidationIssue>>(e); | ||
} |
Check notice
Code scanning / CodeQL
Generic catch clause Note
foreach (var file in files) | ||
{ | ||
var data = File.ReadAllText(file); | ||
ExpressionValidationTestModel testCase = JsonSerializer.Deserialize<ExpressionValidationTestModel>( | ||
data, | ||
JsonSerializerOptions)!; | ||
yield return new object[] { testCase }; | ||
} |
Check notice
Code scanning / CodeQL
Missed opportunity to use Select Note test
maps its iteration variable to another variable
Quality Gate passedThe SonarCloud Quality Gate passed, but some issues were introduced. 14 New issues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving in order to merge, leaving the open conversations to be resolved later.
Combination of #374 and #384
Patch
New endpoint on the DataController that allows frontends to update single (or multiple) fields and get updated validation on those fields.
Implement a new PATCH endpoint using https://docs.json-everything.net/path/basics/
New validation
New service
IValidationService:
A ServiceLocator for validation that does the different kinds of validation. Some logic in data element validation to download the actual data if the element specifies AppLogic and can do that kind of deep validation.
New interfaces:
IValidationService
: The rest of the systems does all its validation needs through this service. It does not mutate any state in instance, process or data elements. Old extension points are accessed through this. Gets services from aSerivceProvider
with a service locator pattern.ValidateTask
: Validates that a task is ready for process next. Finds all relevant data elements and other validations to run.ValidateDataElement
: Used for partial or full validation of a single data element.ITaskValidator
: Interface for App developers to add functionality for whole task validation.TaskId
so that we know what tasks to trigger the validation for.IDataElementValidator
: Interface for validation of data elements without loading the actual content of the data element.IFormDataValidator
: Interface for App developers to add incremental validation to form data elements.DataType
to detect what Data elements to apply the validation to.ShouldRun
and aCode
that is automatically added to all validation issues allows many classes to be registered, but only run when relevant fields are changed. This means that the whole validation implementation needs to either run, or not run to ensure that we can tell front-end what validations has been updated and possibly fixed.New functionality
GenericFormDataValidator
: abstract class that app developers can use to simplify the implementation ofIFormDataValidator
adding a few convenience methodsValidateFormData
that gets the typed model, instead ofobject data
CreateValidationIssue
: Very convenient way of adding errors.m=>m.field.children[1].name
instead of a json path to bind the error to a field.AsyncLocal
to not have to pass or return a list of issues. Just causes less clutter, and works even if the service is registered as a singleton.LinqExpressionHelpers
: static methods to allow parsing of expressions instead of strings to create json paths.Validator registration
Validators can be registered in 3 ways
DataType
orTaskId
is set as"*"
and it is registered as a service in dependency injectionDataType
/TaskId
, set as a specific DataType or task to run (Typically custom validator in a specific app)DataType
/TaskId
and run on a general validator on a specific type)Compatibility
IValidation
, together withValidationAppSI
has been removed and all standard shared validation has been moved to default validatorsDataAnnotationValidation
: Runs attribute validation fromSystem.ComponentModel.DataAnnotations
(eg:[RegEx()]
)DefaultDataElementValidation
: Validates maxSize, contentType, and fileScanDefaultTaskValidator
: Validates min and max count for data elementsExpressionValidator
: Validates data elements with app logic and ensures that expression validation has run.LegacyIInstanceValidatorFormDataValidator
: Runs existingIInstanceValidator.ValidateData
class registered in dependency injection for backwards compatibilityLegacyIInstanceValidatorTaskValidator
: Runs existingIInstanceValidator.ValidateTask
class registered in dependency injection for backwards compatibilityRequiredLayoutValidator
: Runs expressions in layout to ensure that every visible component with"required"
actually has data.Related Issue(s)
Verification
Documentation