use of org.ehrbase.response.openehr.OriginalVersionResponseData in project ehrbase by ehrbase.
the class CustomMethodSecurityExpressionRoot method templateHandling.
/**
* Handles template ID extraction of specific payload.
* <p>
* Payload will be a response body string, in case of @PostAuthorize.
* <p>
* Payload will be request body string, or already deserialized object (e.g. EhrStatus), in case of @PreAuthorize.
* @param type Object type of scope
* @param payload Payload object, either request's input or response's output
* @param contentType Content type from the scope
* @param requestMap ABAC request attribute map to add the result
* @param authType Pre- or PostAuthorize, determines payload style (string or object)
*/
private void templateHandling(String type, Object payload, String contentType, Map<String, Object> requestMap, String authType) {
switch(type) {
case BaseController.EHR:
throw new IllegalArgumentException("ABAC: Unsupported configuration: Can't set template ID for EHR type.");
case BaseController.EHR_STATUS:
throw new IllegalArgumentException("ABAC: Unsupported configuration: Can't set template ID for EHR_STATUS type.");
case BaseController.COMPOSITION:
String content = "";
if (authType.equals(POST)) {
// @PostAuthorize gives a ResponseEntity type for "returnObject", so payload is of that type
if (((ResponseEntity) payload).hasBody()) {
Object body = ((ResponseEntity) payload).getBody();
// can have "No content" here (even with some data in the body) if the compo was (logically) deleted
if (((ResponseEntity<?>) payload).getStatusCode().equals(HttpStatus.NO_CONTENT)) {
if (body instanceof Map) {
Object error = ((Map<?, ?>) body).get("error");
if (error != null) {
if (((String) error).contains("delet")) {
// composition was deleted, so nothing to check here, skip
break;
}
}
}
throw new InternalServerException("ABAC: Unexpected empty response from composition reuquest");
}
if (body instanceof OriginalVersionResponseData) {
// case of versioned_composition --> fast path, because template is easy to get
if (((OriginalVersionResponseData<?>) body).getData() instanceof Composition) {
String template = Objects.requireNonNull(((Composition) ((OriginalVersionResponseData<?>) body).getData()).getArchetypeDetails().getTemplateId()).getValue();
requestMap.put(TEMPLATE, template);
// special case, so done here, exit
break;
}
} else if (body instanceof String) {
content = (String) body;
} else {
throw new InternalServerException("ABAC: unexpected composition payload object");
}
} else {
throw new InternalServerException("ABAC: unexpected empty response body");
}
} else if (authType.equals(PRE)) {
try {
// try if this is the Delete composition case. Payload would contain the UUID of the compo.
ObjectVersionId versionId = new ObjectVersionId((String) payload);
UUID compositionUid = UUID.fromString(versionId.getRoot().getValue());
Optional<CompositionDto> compoDto = compositionService.retrieve(compositionUid, null);
if (compoDto.isPresent()) {
Composition c = compoDto.get().getComposition();
requestMap.put(TEMPLATE, c.getArchetypeDetails().getTemplateId().getValue());
// special case, so done here, exit
break;
} else {
throw new InternalServerException("ABAC: unexpected empty response from composition delete");
}
} catch (IllegalArgumentException e) {
// if not an UUID, the payload is a composition itself so continue
content = (String) payload;
}
} else {
throw new InternalServerException("ABAC: invalid auth type given.");
}
String templateId;
if (MediaType.parseMediaType(contentType).isCompatibleWith(MediaType.APPLICATION_JSON)) {
templateId = compositionService.getTemplateIdFromInputComposition(content, CompositionFormat.JSON);
} else if (MediaType.parseMediaType(contentType).isCompatibleWith(MediaType.APPLICATION_XML)) {
templateId = compositionService.getTemplateIdFromInputComposition(content, CompositionFormat.XML);
} else {
throw new IllegalArgumentException("ABAC: Only JSON and XML composition are supported.");
}
requestMap.put(TEMPLATE, templateId);
break;
case BaseController.CONTRIBUTION:
CompositionFormat format;
if (MediaType.parseMediaType(contentType).isCompatibleWith(MediaType.APPLICATION_JSON)) {
format = CompositionFormat.JSON;
} else if (MediaType.parseMediaType(contentType).isCompatibleWith(MediaType.APPLICATION_XML)) {
format = CompositionFormat.XML;
} else {
throw new IllegalArgumentException("ABAC: Only JSON and XML composition are supported.");
}
if (payload instanceof String) {
Set<String> templates = contributionService.getListOfTemplates((String) payload, format);
requestMap.put(TEMPLATE, templates);
break;
} else {
throw new InternalServerException("ABAC: invalid POST contribution payload.");
}
case BaseController.QUERY:
// special case of type QUERY, where multiple subjects are possible
if (payload instanceof Map) {
if (((Map<?, ?>) payload).containsKey(AuditVariables.TEMPLATE_PATH)) {
Set<String> templates = (Set) ((Map<?, ?>) payload).get(AuditVariables.TEMPLATE_PATH);
Set<String> templateSet = new HashSet<>(templates);
// put result set into the requestMap and exit
requestMap.put(TEMPLATE, templateSet);
break;
} else {
throw new InternalServerException("ABAC: AQL audit template data unavailable.");
}
} else {
throw new InternalServerException("ABAC: AQL audit template data malformed.");
}
default:
throw new InternalServerException("ABAC: Invalid type given from Pre- or PostAuthorize");
}
}
use of org.ehrbase.response.openehr.OriginalVersionResponseData in project ehrbase by ehrbase.
the class OpenehrVersionedCompositionController method getOriginalVersionResponseDataResponseEntity.
private ResponseEntity<OriginalVersionResponseData<Composition>> getOriginalVersionResponseDataResponseEntity(String accept, UUID ehrId, UUID versionedObjectId, int version) {
Optional<OriginalVersion<Composition>> compositionOriginalVersion = compositionService.getOriginalVersionComposition(versionedObjectId, version);
UUID contributionId = compositionOriginalVersion.map(i -> UUID.fromString(i.getContribution().getId().getValue())).orElseThrow(() -> new InvalidApiParameterException("Couldn't retrieve Composition with given parameters"));
Optional<ContributionDto> optionalContributionDto = contributionService.getContribution(ehrId, contributionId);
// shouldn't happen
ContributionDto contributionDto = optionalContributionDto.orElseThrow(() -> new InternalServerException("Couldn't fetch contribution for existing Composition"));
OriginalVersionResponseData<Composition> originalVersionResponseData = new OriginalVersionResponseData<>(compositionOriginalVersion.orElseThrow(() -> new InternalServerException("Composition exists but can't be retrieved as Original Version.")), contributionDto);
HttpHeaders respHeaders = new HttpHeaders();
respHeaders.setContentType(resolveContentType(accept));
return ResponseEntity.ok().headers(respHeaders).body(originalVersionResponseData);
}
use of org.ehrbase.response.openehr.OriginalVersionResponseData in project ehrbase by ehrbase.
the class OpenehrVersionedEhrStatusController method retrieveVersionOfEhrStatusByVersionUid.
@GetMapping(path = "/version/{version_uid}")
// checkAbacPre /-Post attributes (type, subject, payload, content type)
@PreAuthorize("checkAbacPre(@openehrVersionedEhrStatusController.EHR_STATUS, " + "@ehrService.getSubjectExtRef(#ehrIdString), null, null)")
@Override
public ResponseEntity<OriginalVersionResponseData<EhrStatus>> retrieveVersionOfEhrStatusByVersionUid(@RequestHeader(value = HttpHeaders.ACCEPT, required = false) String accept, @PathVariable(value = "ehr_id") String ehrIdString, @PathVariable(value = "version_uid") String versionUid) {
UUID ehrId = getEhrUuid(ehrIdString);
// check if EHR is valid
if (!ehrService.hasEhr(ehrId)) {
throw new ObjectNotFoundException("ehr", "No EHR with this ID can be found.");
}
// parse given version uid
UUID versionedObjectId;
int version;
try {
versionedObjectId = UUID.fromString(versionUid.split("::")[0]);
version = Integer.parseInt(versionUid.split("::")[2]);
} catch (Exception e) {
throw new InvalidApiParameterException("VERSION UID parameter has wrong format: " + e.getMessage());
}
if (version < 1)
throw new InvalidApiParameterException("Version can't be negative.");
if (!ehrService.hasStatus(versionedObjectId)) {
throw new ObjectNotFoundException("ehr_status", "No EHR_STATUS with given ID can be found.");
}
Optional<OriginalVersion<EhrStatus>> ehrStatusOriginalVersion = ehrService.getEhrStatusAtVersion(ehrId, versionedObjectId, version);
UUID contributionId = ehrStatusOriginalVersion.map(i -> UUID.fromString(i.getContribution().getId().getValue())).orElseThrow(() -> new InvalidApiParameterException("Couldn't retrieve EhrStatus with given parameters"));
Optional<ContributionDto> optionalContributionDto = contributionService.getContribution(ehrId, contributionId);
// shouldn't happen
ContributionDto contributionDto = optionalContributionDto.orElseThrow(() -> new InternalServerException("Couldn't fetch contribution for existing EhrStatus"));
OriginalVersionResponseData<EhrStatus> originalVersionResponseData = new OriginalVersionResponseData<>(ehrStatusOriginalVersion.get(), contributionDto);
HttpHeaders respHeaders = new HttpHeaders();
respHeaders.setContentType(resolveContentType(accept));
return ResponseEntity.ok().headers(respHeaders).body(originalVersionResponseData);
}
use of org.ehrbase.response.openehr.OriginalVersionResponseData in project ehrbase by ehrbase.
the class OpenehrVersionedEhrStatusController method retrieveVersionOfEhrStatusByTime.
@GetMapping(path = "/version")
// checkAbacPre /-Post attributes (type, subject, payload, content type)
@PreAuthorize("checkAbacPre(@openehrVersionedEhrStatusController.EHR_STATUS, " + "@ehrService.getSubjectExtRef(#ehrIdString), null, null)")
@Override
public ResponseEntity<OriginalVersionResponseData<EhrStatus>> retrieveVersionOfEhrStatusByTime(@RequestHeader(value = HttpHeaders.ACCEPT, required = false) String accept, @PathVariable(value = "ehr_id") String ehrIdString, @RequestParam(value = "version_at_time", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime versionAtTime) {
UUID ehrId = getEhrUuid(ehrIdString);
// check if EHR is valid
if (!ehrService.hasEhr(ehrId)) {
throw new ObjectNotFoundException("ehr", "No EHR with this ID can be found");
}
UUID versionedObjectId = ehrService.getEhrStatusVersionedObjectUidByEhr(ehrId);
int version;
if (versionAtTime != null) {
version = ehrService.getEhrStatusVersionByTimestamp(ehrId, Timestamp.valueOf(versionAtTime));
} else {
version = Integer.parseInt(ehrService.getLatestVersionUidOfStatus(ehrId).split("::")[2]);
}
Optional<OriginalVersion<EhrStatus>> ehrStatusOriginalVersion = ehrService.getEhrStatusAtVersion(ehrId, versionedObjectId, version);
UUID contributionId = ehrStatusOriginalVersion.map(i -> UUID.fromString(i.getContribution().getId().getValue())).orElseThrow(() -> new InvalidApiParameterException("Couldn't retrieve EhrStatus with given parameters"));
Optional<ContributionDto> optionalContributionDto = contributionService.getContribution(ehrId, contributionId);
// shouldn't happen
ContributionDto contributionDto = optionalContributionDto.orElseThrow(() -> new InternalServerException("Couldn't fetch contribution for existing EhrStatus"));
OriginalVersionResponseData<EhrStatus> originalVersionResponseData = new OriginalVersionResponseData<>(ehrStatusOriginalVersion.get(), contributionDto);
HttpHeaders respHeaders = new HttpHeaders();
respHeaders.setContentType(resolveContentType(accept));
return ResponseEntity.ok().headers(respHeaders).body(originalVersionResponseData);
}
Aggregations