public async Task <ActionResult> Get( [FromRoute] string org, [FromRoute] string app, [FromRoute] int instanceOwnerPartyId, [FromRoute] Guid instanceGuid) { EnforcementResult enforcementResult = await AuthorizeAction(org, app, instanceOwnerPartyId, instanceGuid, "read"); if (!enforcementResult.Authorized) { return(Forbidden(enforcementResult)); } try { Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid); SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request); string userOrgClaim = User.GetOrg(); if (userOrgClaim == null || !org.Equals(userOrgClaim, StringComparison.InvariantCultureIgnoreCase)) { await _instanceService.UpdateReadStatus(instanceOwnerPartyId, instanceGuid, "read"); } return(Ok(instance)); } catch (Exception exception) { return(ExceptionResponse(exception, $"Get instance {instanceOwnerPartyId}/{instanceGuid} failed")); } }
public async Task <ActionResult> Get( [FromRoute] string org, [FromRoute] string app, [FromRoute] int instanceOwnerPartyId, [FromRoute] Guid instanceGuid) { EnforcementResult enforcementResult = await AuthorizeAction(org, app, instanceOwnerPartyId, "read"); if (!enforcementResult.Authorized) { if (enforcementResult.FailedObligations != null && enforcementResult.FailedObligations.Count > 0) { return(StatusCode((int)HttpStatusCode.Forbidden, enforcementResult.FailedObligations)); } return(StatusCode((int)HttpStatusCode.Forbidden)); } try { Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid); SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request); return(Ok(instance)); } catch (PlatformHttpException e) { return(HandlePlatformHttpException(e, $"Get instance {instanceOwnerPartyId}/{instanceGuid} failed")); } catch (Exception exception) { return(ExceptionResponse(exception, $"Get instance {instanceOwnerPartyId}/{instanceGuid} failed")); } }
public async Task <ActionResult> Put( [FromRoute] string org, [FromRoute] string app, [FromRoute] int instanceOwnerPartyId, [FromRoute] Guid instanceGuid, [FromBody] Instance instance) { if (instance == null || !org.Equals(instance.Org) || !instance.AppId.EndsWith(app) || !instanceOwnerPartyId.Equals(int.Parse(instance.InstanceOwner.PartyId)) || !instance.Id.EndsWith(instanceGuid.ToString())) { return(BadRequest($"Inconsistent values between path params and instance attributes")); } try { Instance updatedInstance = await _instanceService.UpdateInstance(instance); if (updatedInstance == null) { return(NotFound()); } SelfLinkHelper.SetInstanceAppSelfLinks(updatedInstance, Request); return(Ok(updatedInstance)); } catch (Exception exception) { return(ExceptionResponse(exception, $"Update of instance {instanceOwnerPartyId}/{instanceGuid} failed.")); } }
public async Task <ActionResult <Instance> > UpdateSubstatus( [FromRoute] string org, [FromRoute] string app, [FromRoute] int instanceOwnerPartyId, [FromRoute] Guid instanceGuid, [FromBody] Substatus substatus) { if (substatus == null || string.IsNullOrEmpty(substatus.Label)) { return(BadRequest($"Invalid sub status: {JsonConvert.SerializeObject(substatus)}. Substatus must be defined and include a label.")); } Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid); string orgClaim = User.GetOrg(); if (!instance.Org.Equals(orgClaim)) { return(Forbid()); } try { Instance updatedInstance = await _instanceService.UpdateSubstatus(instanceOwnerPartyId, instanceGuid, substatus); SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request); return(Ok(updatedInstance)); } catch (Exception exception) { return(ExceptionResponse(exception, $"Updating substatus for instance {instanceOwnerPartyId}/{instanceGuid} failed.")); } }
private async Task <ActionResult> PutBinaryData(string org, string app, int instanceOwnerPartyId, Guid instanceGuid, Guid dataGuid) { DataElement dataElement = await _dataService.UpdateBinaryData(org, app, instanceOwnerPartyId, instanceGuid, dataGuid, Request); SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, dataElement, Request); return(Created(dataElement.SelfLinks.Apps, dataElement)); }
private async Task<ActionResult> PutFormData(string org, string app, Instance instance, Guid dataGuid, string dataType) { string classRef = _appResourcesService.GetClassRefForLogicDataType(dataType); Guid instanceGuid = Guid.Parse(instance.Id.Split("/")[1]); ModelDeserializer deserializer = new ModelDeserializer(_logger, _altinnApp.GetAppModelType(classRef)); object serviceModel = await deserializer.DeserializeAsync(Request.Body, Request.ContentType); if (!string.IsNullOrEmpty(deserializer.Error)) { return BadRequest(deserializer.Error); } if (serviceModel == null) { return BadRequest("No data found in content"); } string serviceModelJsonString = JsonSerializer.Serialize(serviceModel); // Trigger application business logic bool changedByCalculation = await _altinnApp.RunCalculation(serviceModel); int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId); // Save Formdata to database DataElement updatedDataElement = await _dataService.UpdateData( serviceModel, instanceGuid, _altinnApp.GetAppModelType(classRef), org, app, instanceOwnerPartyId, dataGuid); SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, updatedDataElement, Request); string dataUrl = updatedDataElement.SelfLinks.Apps; if (changedByCalculation) { string updatedServiceModelString = JsonSerializer.Serialize(serviceModel); CalculationResult calculationResult = new CalculationResult(updatedDataElement); try { Dictionary<string, object> changedFields = JsonHelper.FindChangedFields(serviceModelJsonString, updatedServiceModelString); calculationResult.ChangedFields = changedFields; } catch (Exception e) { _logger.LogError(e, "Unable to determine changed fields"); } return StatusCode((int)HttpStatusCode.SeeOther, calculationResult); } return Created(dataUrl, updatedDataElement); }
private async Task <ActionResult> CreateAppModelData( string org, string app, Instance instance, string dataType) { Guid instanceGuid = Guid.Parse(instance.Id.Split("/")[1]); object appModel; string classRef = _appResourcesService.GetClassRefForLogicDataType(dataType); if (Request.ContentType == null) { appModel = _altinnApp.CreateNewAppModel(classRef); } else { ModelDeserializer deserializer = new ModelDeserializer(_logger, _altinnApp.GetAppModelType(classRef)); appModel = await deserializer.DeserializeAsync(Request.Body, Request.ContentType); if (!string.IsNullOrEmpty(deserializer.Error)) { return(BadRequest(deserializer.Error)); } } // runs prefill from repo configuration if config exists await _prefillService.PrefillDataModel(instance.InstanceOwner.PartyId, dataType, appModel); // send events to trigger application business logic await _altinnApp.RunDataCreation(instance, appModel); Dictionary <string, string> updatedValues = DataHelper.GetUpdatedDataValues( _appResourcesService.GetApplication().PresentationFields, instance.PresentationTexts, dataType, appModel); if (updatedValues.Count > 0) { await _instanceService.UpdatePresentationTexts( int.Parse(instance.InstanceOwner.PartyId), Guid.Parse(instance.Id.Split("/")[1]), new PresentationTexts { Texts = updatedValues }); } int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId); DataElement dataElement = await _dataService.InsertFormData(appModel, instanceGuid, _altinnApp.GetAppModelType(classRef), org, app, instanceOwnerPartyId, dataType); SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, dataElement, Request); return(Created(dataElement.SelfLinks.Apps, dataElement)); }
private async Task <ActionResult> PutBinaryData(string org, string app, int instanceOwnerPartyId, Guid instanceGuid, Guid dataGuid) { DataElement dataElement = await _dataService.UpdateBinaryData(org, app, instanceOwnerPartyId, instanceGuid, dataGuid, Request); if (dataElement.Locked) { return(Conflict($"Data element {dataGuid} is locked and cannot be updated")); } SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, dataElement, Request); return(Created(dataElement.SelfLinks.Apps, dataElement)); }
private async Task <ActionResult> CreateBinaryData(string org, string app, Instance instanceBefore, string dataType) { int instanceOwnerPartyId = int.Parse(instanceBefore.Id.Split("/")[0]); Guid instanceGuid = Guid.Parse(instanceBefore.Id.Split("/")[1]); DataElement dataElement = await _dataService.InsertBinaryData(org, app, instanceOwnerPartyId, instanceGuid, dataType, Request); if (Guid.Parse(dataElement.Id) == Guid.Empty) { return(StatusCode(500, $"Cannot store form attachment on instance {instanceOwnerPartyId}/{instanceGuid}")); } SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, dataElement, Request); return(Created(dataElement.SelfLinks.Apps, dataElement)); }
public async Task <ActionResult <Instance> > AddCompleteConfirmation( [FromRoute] int instanceOwnerPartyId, [FromRoute] Guid instanceGuid) { try { Instance instance = await _instanceService.AddCompleteConfirmation(instanceOwnerPartyId, instanceGuid); SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request); return(Ok(instance)); } catch (Exception exception) { return(ExceptionResponse(exception, $"Adding complete confirmation to instance {instanceOwnerPartyId}/{instanceGuid} failed")); } }
private async Task <ActionResult> PutFormData(string org, string app, Instance instance, Guid dataGuid, string dataType) { string classRef = _appResourcesService.GetClassRefForLogicDataType(dataType); Guid instanceGuid = Guid.Parse(instance.Id.Split("/")[1]); ModelDeserializer deserializer = new ModelDeserializer(_logger, _altinnApp.GetAppModelType(classRef)); object serviceModel = await deserializer.DeserializeAsync(Request.Body, Request.ContentType); if (!string.IsNullOrEmpty(deserializer.Error)) { return(BadRequest(deserializer.Error)); } if (serviceModel == null) { return(BadRequest("No data found in content")); } // Trigger application business logic bool changedByCalculation = await _altinnApp.RunCalculation(serviceModel); int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId); // Save Formdata to database DataElement updatedDataElement = await _dataService.UpdateData( serviceModel, instanceGuid, _altinnApp.GetAppModelType(classRef), org, app, instanceOwnerPartyId, dataGuid); SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, updatedDataElement, Request); string dataUrl = updatedDataElement.SelfLinks.Apps; if (changedByCalculation) { return(StatusCode((int)HttpStatusCode.SeeOther, updatedDataElement)); } return(Created(dataUrl, updatedDataElement)); }
public async Task <ActionResult <Instance> > DeleteInstance( [FromRoute] int instanceOwnerPartyId, [FromRoute] Guid instanceGuid, [FromQuery] bool hard) { try { Instance deletedInstance = await _instanceService.DeleteInstance(instanceOwnerPartyId, instanceGuid, hard); SelfLinkHelper.SetInstanceAppSelfLinks(deletedInstance, Request); return(Ok(deletedInstance)); } catch (Exception exception) { return(ExceptionResponse(exception, $"Deleting instance {instanceOwnerPartyId}/{instanceGuid} failed.")); } }
private async Task <ActionResult> PutFormData(string org, string app, Instance instance, Guid dataGuid, string dataType) { string classRef = _appResourcesService.GetClassRefForLogicDataType(dataType); Guid instanceGuid = Guid.Parse(instance.Id.Split("/")[1]); object serviceModel = ParseContentAndDeserializeServiceModel(_altinnApp.GetAppModelType(classRef), out ActionResult contentError); if (contentError != null) { return(contentError); } if (serviceModel == null) { return(BadRequest("No data found in content")); } // send events to trigger application business logic await _altinnApp.RunAppEvent(AppEventType.DataRetrieval, serviceModel); await _altinnApp.RunAppEvent(AppEventType.Calculation, serviceModel); int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId); // Save Formdata to database DataElement updatedDataElement = await _dataService.UpdateData( serviceModel, instanceGuid, _altinnApp.GetAppModelType(classRef), org, app, instanceOwnerPartyId, dataGuid); SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, updatedDataElement, Request); string dataUrl = updatedDataElement.SelfLinks.Apps; return(Created(dataUrl, updatedDataElement)); }
private async Task <ActionResult> CreateAppModelData( string org, string app, Instance instance, string dataType) { Guid instanceGuid = Guid.Parse(instance.Id.Split("/")[1]); object appModel; string classRef = _appResourcesService.GetClassRefForLogicDataType(dataType); if (Request.ContentType == null) { appModel = _altinnApp.CreateNewAppModel(classRef); } else { appModel = ParseContentAndDeserializeServiceModel(_altinnApp.GetAppModelType(classRef), out ActionResult contentError); if (contentError != null) { return(contentError); } } // send events to trigger application business logic await _altinnApp.RunAppEvent(AppEventType.AppModelCreation, appModel); int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId); DataElement dataElement = await _dataService.InsertFormData(appModel, instanceGuid, _altinnApp.GetAppModelType(classRef), org, app, instanceOwnerPartyId, dataType); SelfLinkHelper.SetDataAppSelfLinks(instanceOwnerPartyId, instanceGuid, dataElement, Request); return(Created(dataElement.SelfLinks.Apps, dataElement)); }
public async Task <ActionResult> Get( [FromRoute] string org, [FromRoute] string app, [FromRoute] int instanceOwnerPartyId, [FromRoute] Guid instanceGuid) { try { Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid); if (instance == null) { return(NotFound()); } SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request); return(Ok(instance)); } catch (Exception exception) { return(ExceptionResponse(exception, $"Get instance {instanceOwnerPartyId}/{instanceGuid} failed")); } }
public async Task <ActionResult> Get( [FromRoute] string org, [FromRoute] string app, [FromRoute] int instanceOwnerPartyId, [FromRoute] Guid instanceGuid) { try { Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerPartyId, instanceGuid); if (instance == null) { return(NotFound()); } SelfLinkHelper.SetInstanceAppSelfLinks(instance, Request); return(Ok(instance)); } catch (Exception ex) { return(StatusCode(500, $"{ex.Message}")); } }
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)); }
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)); }