Пример #1
0
        public async Task <ActionResult> Create(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromRoute] int instanceOwnerPartyId,
            [FromRoute] Guid instanceGuid,
            [FromQuery] string dataType)
        {
            if (string.IsNullOrWhiteSpace(dataType))
            {
                return(BadRequest("Element type must be provided."));
            }

            Application application = _appResourcesService.GetApplication();

            if (application == null)
            {
                return(NotFound($"AppId {org}/{app} was not found"));
            }

            DataType dataTypeFromMetadata = application.DataTypes.FirstOrDefault(e => e.Id.Equals(dataType, StringComparison.InvariantCultureIgnoreCase));

            if (dataTypeFromMetadata == null)
            {
                return(BadRequest($"Element type {dataType} not allowed for instance {instanceGuid}."));
            }

            try
            {
                bool appLogic = dataTypeFromMetadata.AppLogic != null;

                Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid);

                if (instance == null)
                {
                    return(NotFound($"Did not find instance {instance}"));
                }

                if (appLogic)
                {
                    return(await CreateAppModelData(org, app, instance, dataType));
                }
                else
                {
                    return(await CreateBinaryData(org, app, instance, dataType));
                }
            }
            catch (PlatformHttpException pce)
            {
                return(ExceptionResponse(pce, $"Cannot create data element of {dataType} for {instanceOwnerPartyId}/{instanceGuid}"));
            }
        }
Пример #2
0
        public async Task <IActionResult> Get(string org, string app, bool allowedToInstantiateFilter = false)
        {
            UserContext  userContext = _userHelper.GetUserContext(HttpContext).Result;
            List <Party> partyList   = _authorization.GetPartyList(userContext.UserId);

            if (allowedToInstantiateFilter)
            {
                Application  application  = _appResourcesService.GetApplication();
                List <Party> validParties = InstantiationHelper.FilterPartiesByAllowedPartyTypes(partyList, application.PartyTypesAllowed);
                return(Ok(validParties));
            }

            return(Ok(partyList));
        }
Пример #3
0
        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));
        }
Пример #4
0
 /// <summary>
 /// Initialize a new instance of <see cref="AppBase"/> class with the given services.
 /// </summary>
 /// <param name="resourceService">The service giving access to local resources.</param>
 /// <param name="logger">A logging service.</param>
 /// <param name="dataService">The service giving access to data.</param>
 /// <param name="processService">The service giving access the App process.</param>
 /// <param name="pdfService">The service giving access to the PDF generator.</param>
 /// <param name="prefillService">The service giving access to prefill mechanisms.</param>
 /// <param name="instanceService">The service giving access to instance data</param>
 /// <param name="registerService">The service giving access to register data</param>
 /// <param name="settings">the general settings</param>
 /// <param name="profileService">the profile service</param>
 /// <param name="textService">The text service</param>
 /// <param name="httpContextAccessor">the httpContextAccessor</param>
 /// <param name="eFormidlingClient">The eFormidling client</param>
 /// <param name="appSettings">The appsettings</param>
 protected AppBase(
     IAppResources resourceService,
     ILogger <AppBase> logger,
     IData dataService,
     IProcess processService,
     IPDF pdfService,
     IPrefill prefillService,
     IInstance instanceService,
     IRegister registerService,
     IOptions <GeneralSettings> settings,
     IProfile profileService,
     IText textService,
     IHttpContextAccessor httpContextAccessor,
     IEFormidlingClient eFormidlingClient = null,
     IOptions <AppSettings> appSettings   = null)
 {
     _appMetadata         = resourceService.GetApplication();
     _resourceService     = resourceService;
     _logger              = logger;
     _dataService         = dataService;
     _processService      = processService;
     _pdfService          = pdfService;
     _prefillService      = prefillService;
     _instanceService     = instanceService;
     _registerService     = registerService;
     _userHelper          = new UserHelper(profileService, registerService, settings);
     _profileService      = profileService;
     _textService         = textService;
     _httpContextAccessor = httpContextAccessor;
     _appSettings         = appSettings?.Value;
     _eFormidlingClient   = eFormidlingClient;
 }
Пример #5
0
        /// <inheritdoc/>
        public async Task GenerateAndStoreReceiptPDF(Instance instance)
        {
            string      app             = instance.AppId.Split("/")[1];
            string      org             = instance.Org;
            int         instanceOwnerId = int.Parse(instance.InstanceOwner.PartyId);
            Application application     = _appResourcesService.GetApplication();
            Guid        instanceGuid    = Guid.Parse(instance.Id.Split("/")[1]);

            DataType dataModelDataElement     = application.DataTypes.Find(element => element.AppLogic != null);
            Guid     dataModelDataElementGuid = Guid.Parse(instance.Data.Find(element => element.DataType.Equals(dataModelDataElement.Id))?.Id);

            Stream dataStream = await _dataService.GetBinaryData(org, app, instanceOwnerId, instanceGuid, dataModelDataElementGuid);

            byte[] dataAsBytes = new byte[dataStream.Length];
            await dataStream.ReadAsync(dataAsBytes);

            string encodedXml = System.Convert.ToBase64String(dataAsBytes);

            byte[] formLayout    = _appResourcesService.GetAppResource(org, app, _appSettings.FormLayoutJSONFileName);
            byte[] textResources = _appResourcesService.GetText(org, app, "resource.nb.json");

            string formLayoutString    = GetUTF8String(formLayout);
            string textResourcesString = GetUTF8String(textResources);

            PDFContext pdfContext = new PDFContext
            {
                Data          = encodedXml,
                FormLayout    = JsonConvert.DeserializeObject(formLayoutString),
                TextResources = JsonConvert.DeserializeObject(textResourcesString),
                Party         = await _registerService.GetParty(instanceOwnerId),
                Instance      = instance
            };

            Stream pdfContent;

            try
            {
                pdfContent = await GeneratePDF(pdfContext);
            }
            catch (Exception exception)
            {
                _logger.LogError($"Could not generate pdf for {instance.Id}, failed with message {exception.Message}");
                return;
            }

            try
            {
                await StorePDF(pdfContent, instance);
            }
            catch (Exception exception)
            {
                _logger.LogError($"Could not store pdf for {instance.Id}, failed with message {exception.Message}");
                return;
            }
            finally
            {
                pdfContent.Dispose();
            }
        }
Пример #6
0
 public AppBase(
     IAppResources resourceService,
     ILogger <AppBase> logger,
     IData dataService,
     IProcess processService)
 {
     _appMetadata     = resourceService.GetApplication();
     _resourceService = resourceService;
     _logger          = logger;
     _dataService     = dataService;
     _processService  = processService;
 }
Пример #7
0
        /// <inheritdoc/>
        public async Task <string> AddEvent(string eventType, Instance instance)
        {
            string alternativeSubject = null;

            if (!string.IsNullOrWhiteSpace(instance.InstanceOwner.OrganisationNumber))
            {
                alternativeSubject = $"/org/{instance.InstanceOwner.OrganisationNumber}";
            }

            if (!string.IsNullOrWhiteSpace(instance.InstanceOwner.PersonNumber))
            {
                alternativeSubject = $"/person/{instance.InstanceOwner.PersonNumber}";
            }

            CloudEvent cloudEvent = new CloudEvent
            {
                Subject            = $"/party/{instance.InstanceOwner.PartyId}",
                Type               = eventType,
                AlternativeSubject = alternativeSubject,
                Time               = DateTime.UtcNow,
                SpecVersion        = "1.0",
                Source             = new Uri($"https://{instance.Org}.apps.{_generalSettings.HostName}/{instance.AppId}/instances/{instance.Id}")
            };

            string accessToken = _accessTokenGenerator.GenerateAccessToken(_appResources.GetApplication().Org, _appResources.GetApplication().Id.Split("/")[1]);

            string token =
                JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext, _settings.RuntimeCookieName);

            string serializedCloudEvent = JsonSerializer.Serialize(cloudEvent);

            HttpResponseMessage response = await _client.PostAsync(
                token,
                "app",
                new StringContent(serializedCloudEvent, Encoding.UTF8, "application/json"),
                accessToken);

            if (response.IsSuccessStatusCode)
            {
                string eventId = await response.Content.ReadAsStringAsync();

                return(eventId);
            }

            throw await PlatformHttpException.CreateAsync(response);
        }
Пример #8
0
 /// <summary>
 /// Initialize a new instance of <see cref="AppBase"/> class with the given services.
 /// </summary>
 /// <param name="resourceService">The service giving access to local resources.</param>
 /// <param name="logger">A logging service.</param>
 /// <param name="dataService">The service giving access to data.</param>
 /// <param name="processService">The service giving access the App process.</param>
 /// <param name="pdfService">The service giving access to the PDF generator.</param>
 /// <param name="prefillService">The service giving access to prefill mechanisms.</param>
 protected AppBase(
     IAppResources resourceService,
     ILogger <AppBase> logger,
     IData dataService,
     IProcess processService,
     IPDF pdfService,
     IPrefill prefillService,
     IInstance instanceService)
 {
     _appMetadata     = resourceService.GetApplication();
     _resourceService = resourceService;
     _logger          = logger;
     _dataService     = dataService;
     _processService  = processService;
     _pdfService      = pdfService;
     _prefillService  = prefillService;
     _instanceService = instanceService;
 }
        public async Task <IActionResult> GetAction(string org, string app)
        {
            Application application = _appResources.GetApplication();

            if (application != null)
            {
                string wantedAppId = $"{org}/{app}";

                if (application.Id.Equals(wantedAppId))
                {
                    return(Ok(application));
                }

                return(Conflict($"This is {application.Id}, and not the app you are looking for: {wantedAppId}!"));
            }

            return(NotFound());
        }
Пример #10
0
        public async Task <DataElement> InsertBinaryData(string instanceId, string dataType, string contentType, string filename, Stream stream)
        {
            Application app = _applicationService.GetApplication();


            Guid   dataGuid = Guid.NewGuid();
            string dataPath = GetDataPath(app.Org, app.Id.Split("/")[1], Convert.ToInt32(instanceId.Split("/")[0]), new Guid(instanceId.Split("/")[1]));

            DataElement dataElement = new DataElement()
            {
                Id = dataGuid.ToString(), DataType = dataType, ContentType = contentType,
            };

            if (!Directory.Exists(Path.GetDirectoryName(dataPath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(dataPath));
            }

            Directory.CreateDirectory(dataPath + @"blob");

            long filesize;

            using (Stream streamToWriteTo = File.Open(dataPath + @"blob\" + dataGuid.ToString(), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                await stream.CopyToAsync(streamToWriteTo);

                streamToWriteTo.Flush();
                filesize = streamToWriteTo.Length;
            }

            dataElement.Size = filesize;
            string jsonData = JsonConvert.SerializeObject(dataElement);

            using StreamWriter sw = new StreamWriter(dataPath + dataGuid.ToString() + @".json");

            sw.Write(jsonData.ToString());
            sw.Close();

            return(dataElement);
        }
        public async Task <ActionResult <Instance> > Post(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromQuery] int?instanceOwnerPartyId)
        {
            if (string.IsNullOrEmpty(org))
            {
                return(BadRequest("The path parameter 'org' cannot be empty"));
            }

            if (string.IsNullOrEmpty(app))
            {
                return(BadRequest("The path parameter 'app' cannot be empty"));
            }

            Application application = _appResourcesService.GetApplication();

            if (application == null)
            {
                return(NotFound($"AppId {org}/{app} was not found"));
            }

            MultipartRequestReader parsedRequest = new MultipartRequestReader(Request);
            await parsedRequest.Read();

            if (parsedRequest.Errors.Any())
            {
                return(BadRequest($"Error when reading content: {JsonConvert.SerializeObject(parsedRequest.Errors)}"));
            }

            Instance instanceTemplate = await ExtractInstanceTemplate(parsedRequest);

            if (!instanceOwnerPartyId.HasValue && instanceTemplate == null)
            {
                return(BadRequest("Cannot create an instance without an instanceOwner.partyId. Either provide instanceOwner party Id as a query parameter or an instanceTemplate object in the body."));
            }

            if (instanceOwnerPartyId.HasValue && instanceTemplate?.InstanceOwner?.PartyId != null)
            {
                return(BadRequest("You cannot provide an instanceOwnerPartyId as a query param as well as an instance template in the body. Choose one or the other."));
            }

            RequestPartValidator requestValidator = new RequestPartValidator(application);

            string multipartError = requestValidator.ValidateParts(parsedRequest.Parts);

            if (!string.IsNullOrEmpty(multipartError))
            {
                return(BadRequest($"Error when comparing content to application metadata: {multipartError}"));
            }

            if (instanceTemplate != null)
            {
                InstanceOwner lookup = instanceTemplate.InstanceOwner;

                if (lookup == null || lookup.PersonNumber == null && lookup.OrganisationNumber == null && lookup.PartyId == null)
                {
                    return(BadRequest("Error: instanceOwnerPartyId query parameter is empty and InstanceOwner is missing from instance template. You must populate instanceOwnerPartyId or InstanceOwner"));
                }
            }
            else
            {
                // create minimum instance template
                instanceTemplate = new Instance
                {
                    InstanceOwner = new InstanceOwner {
                        PartyId = instanceOwnerPartyId.Value.ToString()
                    }
                };
            }

            Party party;

            try
            {
                party = await LookupParty(instanceTemplate);
            }
            catch (Exception partyLookupException)
            {
                return(NotFound($"Cannot lookup party: {partyLookupException.Message}"));
            }

            EnforcementResult enforcementResult = await AuthorizeAction(org, app, party.PartyId, "instantiate");

            if (!enforcementResult.Authorized)
            {
                if (enforcementResult.FailedObligations != null && enforcementResult.FailedObligations.Count > 0)
                {
                    return(StatusCode((int)HttpStatusCode.Forbidden, enforcementResult.FailedObligations));
                }

                return(StatusCode((int)HttpStatusCode.Forbidden));
            }

            if (!InstantiationHelper.IsPartyAllowedToInstantiate(party, application.PartyTypesAllowed))
            {
                return(StatusCode((int)HttpStatusCode.Forbidden, $"Party {party.PartyId} is not allowed to instantiate this application {org}/{app}"));
            }

            // Run custom app logic to validate instantiation
            InstantiationValidationResult validationResult = await _altinnApp.RunInstantiationValidation(instanceTemplate);

            if (validationResult != null && !validationResult.Valid)
            {
                return(StatusCode((int)HttpStatusCode.Forbidden, validationResult));
            }

            Instance           instance;
            ProcessStateChange processResult;

            try
            {
                // start process and goto next task
                instanceTemplate.Process = null;
                string startEvent = await _altinnApp.OnInstantiateGetStartEvent();

                processResult = _processService.ProcessStartAndGotoNextTask(instanceTemplate, startEvent, User);

                // create the instance
                instance = await _instanceService.CreateInstance(org, app, instanceTemplate);
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Instantiation of appId {org}/{app} failed for party {instanceTemplate.InstanceOwner?.PartyId}"));
            }

            try
            {
                await StorePrefillParts(instance, application, parsedRequest.Parts);

                // get the updated instance
                instance = await _instanceService.GetInstance(app, org, int.Parse(instance.InstanceOwner.PartyId), Guid.Parse(instance.Id.Split("/")[1]));

                // notify app and store events
                await ProcessController.NotifyAppAboutEvents(_altinnApp, instance, processResult.Events);

                await _processService.DispatchProcessEventsToStorage(instance, processResult.Events);
            }
            catch (Exception exception)
            {
                return(ExceptionResponse(exception, $"Instantiation of data elements failed for instance {instance.Id} for party {instanceTemplate.InstanceOwner?.PartyId}"));
            }

            SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request);
            string url = instance.SelfLinks.Apps;

            return(Created(url, instance));
        }
Пример #12
0
        public async Task<ActionResult> Create(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromRoute] int instanceOwnerPartyId,
            [FromRoute] Guid instanceGuid,
            [FromQuery] string dataType)
        {
            if (string.IsNullOrWhiteSpace(dataType))
            {
                return BadRequest("Element type must be provided.");
            }

            /* The Body of the request is read much later when it has been made sure it is worth it. */

            try
            {
                Application application = _appResourcesService.GetApplication();
                if (application == null)
                {
                    return NotFound($"AppId {org}/{app} was not found");
                }

                DataType dataTypeFromMetadata = application.DataTypes.FirstOrDefault(e => e.Id.Equals(dataType, StringComparison.InvariantCultureIgnoreCase));

                if (dataTypeFromMetadata == null)
                {
                    return BadRequest($"Element type {dataType} not allowed for instance {instanceOwnerPartyId}/{instanceGuid}.");
                }

                if (!IsValidContributer(dataTypeFromMetadata, User))
                {
                    return Forbid();
                }

                bool appLogic = dataTypeFromMetadata.AppLogic != null;

                Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid);
                if (instance == null)
                {
                    return NotFound($"Did not find instance {instance}");
                }

                if (!InstanceIsActive(instance))
                {
                    return Conflict($"Cannot upload data for archived or deleted instance {instanceOwnerPartyId}/{instanceGuid}");
                }

                if (appLogic)
                {
                    return await CreateAppModelData(org, app, instance, dataType);
                }
                else
                {
                    if (!CompliesWithDataRestrictions(dataTypeFromMetadata, out string errorMessage))
                    {
                        return BadRequest($"Invalid data provided. Error: {errorMessage}");
                    }

                    return await CreateBinaryData(org, app, instance, dataType);
                }
            }
            catch (PlatformHttpException e)
            {
                return HandlePlatformHttpException(e, $"Cannot create data element of {dataType} for {instanceOwnerPartyId}/{instanceGuid}");
            }
        }
Пример #13
0
        /// <inheritdoc />
        public async Task <UserProfile> GetUserProfile(int userId)
        {
            UserProfile userProfile = null;

            string endpointUrl = $"users/{userId}";
            string token       = JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext, _settings.RuntimeCookieName);

            HttpResponseMessage response = await _client.GetAsync(token, endpointUrl, _accessTokenGenerator.GenerateAccessToken(_appResources.GetApplication().Org, _appResources.GetApplication().Id));

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                userProfile = await response.Content.ReadAsAsync <UserProfile>();
            }
            else
            {
                _logger.LogError($"Getting user profile with userId {userId} failed with statuscode {response.StatusCode}");
            }

            return(userProfile);
        }
Пример #14
0
        /// <inheritdoc/>
        public async Task GenerateAndStoreReceiptPDF(Instance instance, DataElement dataElement)
        {
            string      app             = instance.AppId.Split("/")[1];
            string      org             = instance.Org;
            int         instanceOwnerId = int.Parse(instance.InstanceOwner.PartyId);
            Application application     = _appResourcesService.GetApplication();
            Guid        instanceGuid    = Guid.Parse(instance.Id.Split("/")[1]);

            Stream dataStream = await _dataService.GetBinaryData(org, app, instanceOwnerId, instanceGuid, new Guid(dataElement.Id));

            byte[] dataAsBytes = new byte[dataStream.Length];
            await dataStream.ReadAsync(dataAsBytes);

            string encodedXml = Convert.ToBase64String(dataAsBytes);

            UserContext userContext = await _userHelper.GetUserContext(_httpContextAccessor.HttpContext);

            UserProfile userProfile = await _profileService.GetUserProfile(userContext.UserId);

            byte[]       formLayout   = _appResourcesService.GetAppResource(org, app, _appSettings.FormLayoutJSONFileName);
            TextResource textResource = await _textService.GetText(org, app, userProfile.ProfileSettingPreference.Language);

            string formLayoutString    = GetUTF8String(formLayout);
            string textResourcesString = JsonConvert.SerializeObject(textResource);

            PDFContext pdfContext = new PDFContext
            {
                Data          = encodedXml,
                FormLayout    = JsonConvert.DeserializeObject(formLayoutString),
                TextResources = JsonConvert.DeserializeObject(textResourcesString),
                Party         = await _registerService.GetParty(instanceOwnerId),
                Instance      = instance,
                UserProfile   = userProfile,
                UserParty     = userProfile.Party
            };

            Stream pdfContent;

            try
            {
                pdfContent = await GeneratePDF(pdfContext);
            }
            catch (Exception exception)
            {
                _logger.LogError($"Could not generate pdf for {instance.Id}, failed with message {exception.Message}");
                return;
            }

            try
            {
                await StorePDF(pdfContent, instance, textResource);
            }
            catch (Exception exception)
            {
                _logger.LogError($"Could not store pdf for {instance.Id}, failed with message {exception.Message}");
                return;
            }
            finally
            {
                pdfContent.Dispose();
            }
        }
Пример #15
0
        /// <inheritdoc/>
        public async Task <Party> GetParty(int partyId)
        {
            Party party = null;

            string endpointUrl           = $"parties/{partyId}";
            string token                 = JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext, _settings.RuntimeCookieName);
            HttpResponseMessage response = await _client.GetAsync(token, endpointUrl, _accessTokenGenerator.GenerateAccessToken(_appResources.GetApplication().Org, _appResources.GetApplication().Id));

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                party = await response.Content.ReadAsAsync <Party>();
            }
            else
            {
                _logger.LogError($"// Getting party with partyID {partyId} failed with statuscode {response.StatusCode}");
            }

            return(party);
        }
Пример #16
0
        /// <inheritdoc/>
        public async Task <Person> GetPerson(string SSN)
        {
            Person person = null;

            string endpointUrl = $"persons/{SSN}";

            string token = JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext, _settings.RuntimeCookieName);

            HttpResponseMessage response = await _client.GetAsync(token, endpointUrl, _accessTokenGenerator.GenerateAccessToken(_appResource.GetApplication().Org, _appResource.GetApplication().Id.Split("/")[1]));

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                person = await response.Content.ReadAsAsync <Person>();
            }
            else
            {
                _logger.LogError($"Getting person with ssn {SSN} failed with statuscode {response.StatusCode}");
            }

            return(person);
        }
Пример #17
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);
        }
Пример #18
0
        public async Task <ActionResult <Instance> > Post(
            [FromRoute] string org,
            [FromRoute] string app,
            [FromQuery] int?instanceOwnerPartyId)
        {
            if (string.IsNullOrEmpty(org))
            {
                return(BadRequest("The path parameter 'org' cannot be empty"));
            }

            if (string.IsNullOrEmpty(app))
            {
                return(BadRequest("The path parameter 'app' cannot be empty"));
            }

            Application application = _appResourcesService.GetApplication();

            if (application == null)
            {
                return(NotFound($"AppId {org}/{app} was not found"));
            }

            MultipartRequestReader parsedRequest = new MultipartRequestReader(Request);
            await parsedRequest.Read();

            if (parsedRequest.Errors.Any())
            {
                return(BadRequest($"Error when reading content: {JsonConvert.SerializeObject(parsedRequest.Errors)}"));
            }

            Instance instanceTemplate = ExtractInstanceTemplate(parsedRequest);

            if (!instanceOwnerPartyId.HasValue && instanceTemplate == null)
            {
                return(BadRequest("Cannot create an instance without an instanceOwner.partyId. Either provide instanceOwner party Id as a query parameter or an instanceTemplate object in the body."));
            }

            if (instanceOwnerPartyId.HasValue && instanceTemplate?.InstanceOwner?.PartyId != null)
            {
                return(BadRequest("You cannot provide an instanceOwnerPartyId as a query param as well as an instance template in the body. Choose one or the other."));
            }

            RequestPartValidator requestValidator = new RequestPartValidator(application);

            string multipartError = requestValidator.ValidateParts(parsedRequest.Parts);

            if (!string.IsNullOrEmpty(multipartError))
            {
                return(BadRequest($"Error when comparing content to application metadata: {multipartError}"));
            }

            // extract or create instance template
            if (instanceTemplate != null)
            {
                InstanceOwner lookup = instanceTemplate.InstanceOwner;

                if (string.IsNullOrEmpty(instanceTemplate.InstanceOwner.PartyId) && (lookup == null || (lookup.PersonNumber == null && lookup.OrganisationNumber == null)))
                {
                    return(BadRequest($"Error: instanceOwnerPartyId query parameter is empty and InstanceOwner is missing from instance template. You must populate instanceOwnerPartyId or InstanceOwner"));
                }
            }
            else
            {
                instanceTemplate = new Instance
                {
                    InstanceOwner = new InstanceOwner {
                        PartyId = instanceOwnerPartyId.Value.ToString()
                    }
                };
            }

            Party party;

            try
            {
                party = await LookupParty(instanceTemplate);
            }
            catch (Exception partyLookupException)
            {
                return(NotFound($"Cannot lookup party: {partyLookupException.Message}"));
            }

            XacmlJsonRequestRoot request = DecisionHelper.CreateXacmlJsonRequest(org, app, HttpContext.User, "instantiate", party.PartyId.ToString(), null);
            bool authorized = await _pdp.GetDecisionForUnvalidateRequest(request, HttpContext.User);

            if (!authorized)
            {
                return(Forbid());
            }

            if (!InstantiationHelper.IsPartyAllowedToInstantiate(party, application.PartyTypesAllowed))
            {
                return(Forbid($"Party {party?.PartyId} is not allowed to instantiate this application {org}/{app}"));
            }

            // use process controller to start process
            instanceTemplate.Process = null;

            Instance instance;

            try
            {
                instance = await _instanceService.CreateInstance(org, app, instanceTemplate);

                if (instance == null)
                {
                    throw new PlatformClientException("Failure instantiating instance. UnknownError");
                }
            }
            catch (Exception instanceException)
            {
                string message = $"Failure in multipart prefil. Could not create an instance of {org}/{app} for party {instanceTemplate.InstanceOwner.PartyId}.";

                _logger.LogError($"{message} - {instanceException}");
                return(StatusCode(500, $"{message} - {instanceException.Message}"));
            }

            try
            {
                await StorePrefillParts(instance, application, parsedRequest.Parts);

                // get the updated instance
                instance = await _instanceService.GetInstance(app, org, int.Parse(instance.InstanceOwner.PartyId), Guid.Parse(instance.Id.Split("/")[1]));

                Instance instanceWithStartedProcess = await StartProcessAndGotoNextTask(instance);

                if (instanceWithStartedProcess != null)
                {
                    instance = instanceWithStartedProcess;
                }
                else
                {
                    return(Conflict($"Unable to start and move process to next task for instance {instance.Id}"));
                }
            }
            catch (Exception dataException)
            {
                string message = $"Failure storing multipart prefil data. Could not create a data element for {instance.Id} of {org}/{app}.";
                _logger.LogError($"{message} - {dataException}");

                // todo add compensating transaction (delete instance)
                return(StatusCode(500, $"{message} Exception: {dataException.Message}"));
            }

            SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request);
            string url = instance.SelfLinks.Apps;

            return(Created(url, instance));
        }
Пример #19
0
        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);
        }
Пример #20
0
        /// <inheritdoc />
        public async Task <Organization> GetOrganization(string OrgNr)
        {
            Organization organization = null;

            string endpointUrl = $"organizations/{OrgNr}";
            string token       = JwtTokenUtil.GetTokenFromContext(_httpContextAccessor.HttpContext, _settings.RuntimeCookieName);

            HttpResponseMessage response = await _client.GetAsync(token, endpointUrl, _accessTokenGenerator.GenerateAccessToken(_appResources.GetApplication().Org, _appResources.GetApplication().Id));

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                organization = await response.Content.ReadAsAsync <Organization>();
            }
            else
            {
                _logger.LogError($"Getting organisation with orgnr {OrgNr} failed with statuscode {response.StatusCode}");
            }

            return(organization);
        }
Пример #21
0
        /// <summary>
        /// Validate an instance for a specified process step.
        /// </summary>
        /// <param name="instance">The instance to validate</param>
        /// <param name="taskId">The task to validate the instance for.</param>
        /// <returns>A list of validation errors if any were found</returns>
        public async Task <List <ValidationIssue> > ValidateAndUpdateProcess(Instance instance, string taskId)
        {
            _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));

            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 = ValidationIssueCodes.InstanceCodes.TooManyDataElementsOfType,
                        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 = ValidationIssueCodes.InstanceCodes.TooFewDataElementsOfType,
                        Field       = dataType.Id
                    };
                    messages.Add(message);
                }

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

            instance.Process.CurrentTask.Validated = new ValidationStatus
            {
                // The condition for completion is met if there are no errors (or other weirdnesses).
                CanCompleteTask = messages.Count == 0 ||
                                  messages.All(m => m.Severity != ValidationIssueSeverity.Error && m.Severity != ValidationIssueSeverity.Unspecified),
                Timestamp = DateTime.Now
            };

            await _instanceService.UpdateProcess(instance);

            return(messages);
        }