Exemple #1
0
        public async Task Instance_Post_WithInstantiationValidationFail()
        {
            string token = PrincipalUtil.GetToken(1337);

            HttpClient client = SetupUtil.GetTestClient(_factory, "tdd", "custom-validation");

            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "/tdd/custom-validation/instances?instanceOwnerPartyId=1337")
            {
            };

            HttpResponseMessage response = await client.SendAsync(httpRequestMessage);

            string responseContent = await response.Content.ReadAsStringAsync();

            InstantiationValidationResult validationResult = JsonConvert.DeserializeObject <InstantiationValidationResult>(responseContent);

            if (DateTime.Now.Hour < 15)
            {
                Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
                Assert.False(validationResult.Valid);
                Assert.Equal("ERROR: Instantiation not possible before 3PM.", validationResult.Message);
            }
            else
            {
                Assert.Equal(HttpStatusCode.Created, response.StatusCode);
                Instance createdInstance = JsonConvert.DeserializeObject <Instance>(await response.Content.ReadAsStringAsync());

                Assert.NotNull(createdInstance);
                Assert.Single(createdInstance.Data);
                Assert.Equal("default", createdInstance.Data[0].DataType);

                TestDataUtil.DeleteInstanceAndData("tdd", "custom-validering", 1337, new Guid(createdInstance.Id.Split('/')[1]));
            }
        }
        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));
        }