Example #1
0
        private List <ValidationIssue> MapModelStateToIssueList(
            ModelStateDictionary modelState,
            Instance instance,
            Dictionary <string, Dictionary <string, string> > serviceText)
        {
            List <ValidationIssue> validationIssues = new List <ValidationIssue>();

            foreach (string modelKey in modelState.Keys)
            {
                modelState.TryGetValue(modelKey, out ModelStateEntry entry);

                if (entry != null && entry.ValidationState == ModelValidationState.Invalid)
                {
                    foreach (ModelError error in entry.Errors)
                    {
                        validationIssues.Add(new ValidationIssue()
                        {
                            InstanceId  = instance.Id,
                            Code        = error.ErrorMessage,
                            Severity    = ValidationIssueSeverity.Error,
                            Description = AppTextHelper.GetAppText(error.ErrorMessage, serviceText, null, "nb")
                        });
                    }
                }
            }

            return(validationIssues);
        }
        public async Task <IActionResult> ValidateData(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromRoute] int instanceOwnerId,
            [FromRoute] Guid instanceId,
            [FromRoute] Guid dataGuid)
        {
            Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerId, instanceId);

            if (instance == null)
            {
                return(NotFound());
            }

            // Todo. Figure out where to get this from
            Dictionary <string, Dictionary <string, string> > serviceText = new Dictionary <string, Dictionary <string, string> >();

            if (instance.Process?.CurrentTask?.ElementId == null)
            {
                throw new ValidationException("Unable to validate instance without a started process.");
            }

            List <ValidationIssue> messages = new List <ValidationIssue>();

            DataElement element = instance.Data.FirstOrDefault(d => d.Id == dataGuid.ToString());

            if (element == null)
            {
                throw new ValidationException("Unable to validate data element.");
            }

            Application application = _appResourceService.GetApplication();

            DataType dataType = application.DataTypes.FirstOrDefault(et => et.Id == element.DataType);

            if (dataType == null)
            {
                throw new ValidationException("Unknown element type.");
            }

            messages.AddRange(await _validationService.ValidateDataElement(instance, dataType, element));

            string taskId = instance.Process.CurrentTask.ElementId;

            if (!dataType.TaskId.Equals(taskId, StringComparison.OrdinalIgnoreCase))
            {
                ValidationIssue message = new ValidationIssue
                {
                    Code          = ValidationIssueCodes.DataElementCodes.DataElementValidatedAtWrongTask,
                    InstanceId    = instance.Id,
                    Severity      = ValidationIssueSeverity.Warning,
                    DataElementId = element.Id,
                    Description   = AppTextHelper.GetAppText(
                        ValidationIssueCodes.DataElementCodes.DataElementValidatedAtWrongTask, serviceText, null, "nb")
                };
                messages.Add(message);
            }

            return(Ok(messages));
        }
Example #3
0
        public async Task <List <ValidationIssue> > ValidateAndUpdateProcess(Instance instance, string taskId)
        {
            // Todo. Figure out where to get this from
            Dictionary <string, Dictionary <string, string> > serviceText = new Dictionary <string, Dictionary <string, string> >();

            _logger.LogInformation($"Validation of {instance.Id}");

            List <ValidationIssue> messages = new List <ValidationIssue>();

            ModelStateDictionary validationResults = new ModelStateDictionary();
            await _altinnApp.RunTaskValidation(instance, taskId, validationResults);

            messages.AddRange(MapModelStateToIssueList(validationResults, instance, serviceText));

            Application application = _appResourcesService.GetApplication();

            foreach (DataType dataType in application.DataTypes.Where(et => et.TaskId == taskId))
            {
                List <DataElement> elements = instance.Data.Where(d => d.DataType == dataType.Id).ToList();

                if (dataType.MaxCount > 0 && dataType.MaxCount < elements.Count)
                {
                    ValidationIssue message = new ValidationIssue
                    {
                        InstanceId  = instance.Id,
                        Code        = ValidationIssueCodes.InstanceCodes.TooManyDataElementsOfType,
                        Severity    = ValidationIssueSeverity.Error,
                        Description = AppTextHelper.GetAppText(
                            ValidationIssueCodes.InstanceCodes.TooManyDataElementsOfType, serviceText, null, "nb"),
                        Field = dataType.Id
                    };
                    messages.Add(message);
                }

                if (dataType.MinCount > 0 && dataType.MinCount > elements.Count)
                {
                    ValidationIssue message = new ValidationIssue
                    {
                        InstanceId  = instance.Id,
                        Code        = ValidationIssueCodes.InstanceCodes.TooFewDataElementsOfType,
                        Severity    = ValidationIssueSeverity.Error,
                        Description = AppTextHelper.GetAppText(
                            ValidationIssueCodes.InstanceCodes.TooFewDataElementsOfType, null, null, "nb"),
                        Field = dataType.Id
                    };
                    messages.Add(message);
                }

                foreach (DataElement dataElement in elements)
                {
                    messages.AddRange(await ValidateDataElement(instance, dataType, dataElement));
                }
            }

            if (messages.Count == 0)
            {
                instance.Process.CurrentTask.Validated = new ValidationStatus {
                    CanCompleteTask = true, Timestamp = DateTime.Now
                };
            }
            else
            {
                instance.Process.CurrentTask.Validated = new ValidationStatus {
                    CanCompleteTask = false, Timestamp = DateTime.Now
                };
            }

            instance = await _instanceService.UpdateProcess(instance);

            return(messages);
        }
Example #4
0
        public async Task <List <ValidationIssue> > ValidateDataElement(Instance instance, DataType dataType, DataElement dataElement)
        {
            _logger.LogInformation($"Validation of data element {dataElement.Id} of instance {instance.Id}");

            // Todo. Figure out where to get this from
            Dictionary <string, Dictionary <string, string> > serviceText = new Dictionary <string, Dictionary <string, string> >();

            List <ValidationIssue> messages = new List <ValidationIssue>();

            if (dataElement.ContentType == null)
            {
                ValidationIssue message = new ValidationIssue
                {
                    InstanceId    = instance.Id,
                    Code          = ValidationIssueCodes.DataElementCodes.MissingContentType,
                    DataElementId = dataElement.Id,
                    Severity      = ValidationIssueSeverity.Error,
                    Description   = AppTextHelper.GetAppText(
                        ValidationIssueCodes.DataElementCodes.MissingContentType, serviceText, null, "nb")
                };
                messages.Add(message);
            }
            else
            {
                string contentTypeWithoutEncoding = dataElement.ContentType.Split(";")[0];

                if (dataType.AllowedContentTypes != null && dataType.AllowedContentTypes.Count > 0 && dataType.AllowedContentTypes.All(ct => !ct.Equals(contentTypeWithoutEncoding, StringComparison.OrdinalIgnoreCase)))
                {
                    ValidationIssue message = new ValidationIssue
                    {
                        InstanceId    = instance.Id,
                        DataElementId = dataElement.Id,
                        Code          = ValidationIssueCodes.DataElementCodes.ContentTypeNotAllowed,
                        Severity      = ValidationIssueSeverity.Error,
                        Description   = AppTextHelper.GetAppText(
                            ValidationIssueCodes.DataElementCodes.ContentTypeNotAllowed, serviceText, null, "nb"),
                        Field = dataType.Id
                    };
                    messages.Add(message);
                }
            }

            if (dataType.MaxSize.HasValue && dataType.MaxSize > 0 && (long)dataType.MaxSize * 1024 * 1024 < dataElement.Size)
            {
                ValidationIssue message = new ValidationIssue
                {
                    InstanceId    = instance.Id,
                    DataElementId = dataElement.Id,
                    Code          = ValidationIssueCodes.DataElementCodes.DataElementTooLarge,
                    Severity      = ValidationIssueSeverity.Error,
                    Description   = AppTextHelper.GetAppText(
                        ValidationIssueCodes.DataElementCodes.DataElementTooLarge, serviceText, null, "nb"),
                    Field = dataType.Id
                };
                messages.Add(message);
            }

            if (dataType.AppLogic != null)
            {
                Type    modelType            = _altinnApp.GetAppModelType(dataType.AppLogic.ClassRef);
                Guid    instanceGuid         = Guid.Parse(instance.Id.Split("/")[1]);
                string  app                  = instance.AppId.Split("/")[1];
                int     instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId);
                dynamic data                 = await _dataService.GetFormData(instanceGuid, modelType, instance.Org, app, instanceOwnerPartyId, Guid.Parse(dataElement.Id));

                ModelStateDictionary validationResults = new ModelStateDictionary();
                var actionContext = new ActionContext(
                    _httpContextAccessor.HttpContext,
                    new Microsoft.AspNetCore.Routing.RouteData(),
                    new ActionDescriptor(),
                    validationResults);

                ValidationStateDictionary validationState = new ValidationStateDictionary();
                _objectModelValidator.Validate(actionContext, validationState, null, data);
                await _altinnApp.RunDataValidation(data, validationResults);

                if (!validationResults.IsValid)
                {
                    messages.AddRange(MapModelStateToIssueList(actionContext.ModelState, instance, dataElement.Id, serviceText));
                }
            }

            return(messages);
        }
        public async Task <System.Collections.Generic.List <ValidationIssue> > ValidateAndUpdateInstance(Instance instance, string taskId)
        {
            string org = instance.Org;
            string app = instance.AppId.Split("/")[1];

            _logger.LogInformation($"Validation of {instance.Id}");

            Application application = _appResourcesService.GetApplication();

            // Todo. Figure out where to get this from
            Dictionary <string, Dictionary <string, string> > serviceText = new Dictionary <string, Dictionary <string, string> >();

            List <ValidationIssue> messages = new List <ValidationIssue>();

            foreach (DataType dataType in application.DataTypes.Where(et => et.TaskId == taskId))
            {
                List <DataElement> elements = instance.Data.Where(d => d.DataType == dataType.Id).ToList();

                if (dataType.MaxCount > 0 && dataType.MaxCount < elements.Count)
                {
                    ValidationIssue message = new ValidationIssue
                    {
                        InstanceId  = instance.Id,
                        Code        = ValidationIssueCodes.InstanceCodes.TooManyDataElementsOfType,
                        Severity    = ValidationIssueSeverity.Error,
                        Description = AppTextHelper.GetAppText(
                            ValidationIssueCodes.InstanceCodes.TooManyDataElementsOfType, serviceText, null, "nb")
                    };
                    messages.Add(message);
                }

                if (dataType.MinCount > 0 && dataType.MinCount > elements.Count)
                {
                    ValidationIssue message = new ValidationIssue
                    {
                        InstanceId  = instance.Id,
                        Code        = ValidationIssueCodes.InstanceCodes.TooFewDataElementsOfType,
                        Severity    = ValidationIssueSeverity.Error,
                        Description = AppTextHelper.GetAppText(
                            ValidationIssueCodes.InstanceCodes.TooFewDataElementsOfType, null, null, "nb")
                    };
                    messages.Add(message);
                }

                foreach (DataElement dataElement in elements)
                {
                    messages.AddRange(await ValidateDataElement(instance, dataType, dataElement));
                }
            }

            if (messages.Count == 0)
            {
                instance.Process.CurrentTask.Validated = new ValidationStatus {
                    CanCompleteTask = true, Timestamp = DateTime.Now
                };
            }
            else
            {
                instance.Process.CurrentTask.Validated = new ValidationStatus {
                    CanCompleteTask = false, Timestamp = DateTime.Now
                };
            }

            return(messages);
        }