Search in sources :

Example 1 with InternalServerException

use of org.ehrbase.api.exception.InternalServerException 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");
    }
}
Also used : CompositionFormat(org.ehrbase.response.ehrscape.CompositionFormat) Composition(com.nedap.archie.rm.composition.Composition) HashSet(java.util.HashSet) Set(java.util.Set) Optional(java.util.Optional) InternalServerException(org.ehrbase.api.exception.InternalServerException) ObjectVersionId(com.nedap.archie.rm.support.identification.ObjectVersionId) OriginalVersionResponseData(org.ehrbase.response.openehr.OriginalVersionResponseData) ResponseEntity(org.springframework.http.ResponseEntity) UUID(java.util.UUID) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 2 with InternalServerException

use of org.ehrbase.api.exception.InternalServerException in project ehrbase by ehrbase.

the class CustomMethodSecurityExpressionRoot method abacCheckRequest.

private boolean abacCheckRequest(String url, Map<String, Object> bodyMap) throws IOException, InterruptedException {
    // prepare request attributes and convert from <String, Object> to <String, String>
    Map<String, String> request = new HashMap<>();
    if (bodyMap.containsKey(ORGANIZATION)) {
        request.put(ORGANIZATION, (String) bodyMap.get(ORGANIZATION));
    }
    // check if patient attribues are available and see if it contains a Set or simple String
    if (bodyMap.containsKey(PATIENT)) {
        if (bodyMap.get(PATIENT) instanceof Set) {
            // check if templates are also configured
            if (bodyMap.containsKey(TEMPLATE)) {
                if (bodyMap.get(TEMPLATE) instanceof Set) {
                    // multiple templates possible: need cartesian product of n patients and m templates
                    // so: for each patient, go through templates and do a request each
                    Set<String> setP = (Set<String>) bodyMap.get(PATIENT);
                    for (String p : setP) {
                        request.put(PATIENT, p);
                        boolean success = sendRequestForEach(TEMPLATE, url, bodyMap, request);
                        if (!success) {
                            return false;
                        }
                    }
                    // in case all combinations were validated successfully
                    return true;
                }
            } else {
                // only patients (or + orga) set. So run request for each patient, without template.
                return sendRequestForEach(PATIENT, url, bodyMap, request);
            }
        } else if (bodyMap.get(PATIENT) instanceof String) {
            request.put(PATIENT, (String) bodyMap.get(PATIENT));
        } else {
            // if it is just a String, set it and continue normal
            throw new InternalServerException("ABAC: Invalid patient attribute content.");
        }
    }
    // check if template attributes are available and see if it contains a Set or simple String
    if (bodyMap.containsKey(TEMPLATE)) {
        if (bodyMap.get(TEMPLATE) instanceof Set) {
            // set each template and send separate ABAC requests
            return sendRequestForEach(TEMPLATE, url, bodyMap, request);
        } else if (bodyMap.get(TEMPLATE) instanceof String) {
            // if it is just a String, set it and continue normal
            request.put(TEMPLATE, (String) bodyMap.get(TEMPLATE));
        } else {
            throw new InternalServerException("ABAC: Invalid template attribute content.");
        }
    }
    return abacCheck.execute(url, request);
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) InternalServerException(org.ehrbase.api.exception.InternalServerException)

Example 3 with InternalServerException

use of org.ehrbase.api.exception.InternalServerException in project ehrbase by ehrbase.

the class TemplateServiceImp method findOperationalTemplate.

@Override
public String findOperationalTemplate(String templateId, OperationalTemplateFormat format) throws ObjectNotFoundException, InvalidApiParameterException, InternalServerException {
    Optional<OPERATIONALTEMPLATE> operationaltemplate;
    if (format.equals(OperationalTemplateFormat.XML)) {
        try {
            operationaltemplate = this.knowledgeCacheService.retrieveOperationalTemplate(templateId);
            if (!operationaltemplate.isPresent()) {
                throw new ObjectNotFoundException("template", "Template with the specified id does not exist");
            }
        } catch (NullPointerException e) {
            // TODO: is this NPE really thrown in case of not found template anymore?
            throw new ObjectNotFoundException("template", "Template with the specified id does not exist", e);
        }
    } else {
        // TODO only XML at the moment
        throw new InvalidApiParameterException("Requested operational template type not supported");
    }
    XmlOptions opts = new XmlOptions();
    opts.setSaveSyntheticDocumentElement(new QName("http://schemas.openehr.org/v1", "template"));
    return operationaltemplate.map(o -> o.xmlText(opts)).orElseThrow(() -> new InternalServerException("Failure while retrieving operational template"));
}
Also used : InvalidApiParameterException(org.ehrbase.api.exception.InvalidApiParameterException) TemplateService(org.ehrbase.api.service.TemplateService) TemplateMetaDataDto(org.ehrbase.response.ehrscape.TemplateMetaDataDto) OPERATIONALTEMPLATE(org.openehr.schemas.v1.OPERATIONALTEMPLATE) TemplateMetaData(org.ehrbase.ehr.knowledge.TemplateMetaData) ObjectNotFoundException(org.ehrbase.api.exception.ObjectNotFoundException) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) CARCHETYPEROOT(org.openehr.schemas.v1.CARCHETYPEROOT) Service(org.springframework.stereotype.Service) DSLContext(org.jooq.DSLContext) OperationalTemplateFormat(org.ehrbase.api.definitions.OperationalTemplateFormat) Logger(org.slf4j.Logger) StructuredStringFormat(org.ehrbase.response.ehrscape.StructuredStringFormat) Collectors(java.util.stream.Collectors) StructuredString(org.ehrbase.response.ehrscape.StructuredString) StandardCharsets(java.nio.charset.StandardCharsets) WebTemplate(org.ehrbase.webtemplate.model.WebTemplate) Objects(java.util.Objects) List(java.util.List) CompositionService(org.ehrbase.api.service.CompositionService) XmlOptions(org.apache.xmlbeans.XmlOptions) InternalServerException(org.ehrbase.api.exception.InternalServerException) InvalidApiParameterException(org.ehrbase.api.exception.InvalidApiParameterException) ServerConfig(org.ehrbase.api.definitions.ServerConfig) Optional(java.util.Optional) QName(javax.xml.namespace.QName) OBJECTID(org.openehr.schemas.v1.OBJECTID) CompositionFormat(org.ehrbase.response.ehrscape.CompositionFormat) Transactional(org.springframework.transaction.annotation.Transactional) OPERATIONALTEMPLATE(org.openehr.schemas.v1.OPERATIONALTEMPLATE) QName(javax.xml.namespace.QName) InternalServerException(org.ehrbase.api.exception.InternalServerException) ObjectNotFoundException(org.ehrbase.api.exception.ObjectNotFoundException) XmlOptions(org.apache.xmlbeans.XmlOptions)

Example 4 with InternalServerException

use of org.ehrbase.api.exception.InternalServerException in project ehrbase by ehrbase.

the class QueryServiceImp method updateStoredQuery.

@Override
public QueryDefinitionResultDto updateStoredQuery(String qualifiedName, String version, String queryString) {
    try {
        I_StoredQueryAccess storedQueryAccess = StoredQueryAccess.retrieveQualified(getDataAccess(), qualifiedName + ((version != null && !version.isEmpty()) ? "/" + version : ""));
        storedQueryAccess.setQueryText(queryString);
        storedQueryAccess.update(Timestamp.from(Instant.now()));
        return mapToQueryDefinitionDto(storedQueryAccess);
    } catch (DataAccessException dae) {
        throw new GeneralRequestProcessingException("Data Access Error:" + dae.getCause().getMessage());
    } catch (IllegalArgumentException iae) {
        throw new IllegalArgumentException(iae.getMessage());
    } catch (Exception e) {
        throw new InternalServerException(e.getMessage());
    }
}
Also used : I_StoredQueryAccess(org.ehrbase.dao.access.interfaces.I_StoredQueryAccess) GeneralRequestProcessingException(org.ehrbase.api.exception.GeneralRequestProcessingException) InternalServerException(org.ehrbase.api.exception.InternalServerException) DataAccessException(org.jooq.exception.DataAccessException) GeneralRequestProcessingException(org.ehrbase.api.exception.GeneralRequestProcessingException) BadGatewayException(org.ehrbase.api.exception.BadGatewayException) RestClientException(org.springframework.web.client.RestClientException) DataAccessException(org.jooq.exception.DataAccessException) InternalServerException(org.ehrbase.api.exception.InternalServerException)

Example 5 with InternalServerException

use of org.ehrbase.api.exception.InternalServerException in project ehrbase by ehrbase.

the class QueryServiceImp method createStoredQuery.

@Override
public QueryDefinitionResultDto createStoredQuery(String qualifiedName, String version, String queryString) {
    // validate the query syntax
    try {
        new AqlExpression().parse(queryString);
    } catch (Exception e) {
        throw new IllegalArgumentException("Invalid query, reason:" + e);
    }
    try {
        String queryQualifiedName = qualifiedName + ((version != null && !version.isEmpty()) ? "/" + version : "");
        I_StoredQueryAccess storedQueryAccess = new StoredQueryAccess(getDataAccess(), queryQualifiedName, queryString);
        storedQueryAccess.commit();
        return mapToQueryDefinitionDto(storedQueryAccess);
    } catch (DataAccessException dae) {
        throw new GeneralRequestProcessingException("Data Access Error:" + dae.getCause().getMessage());
    } catch (IllegalArgumentException iae) {
        throw new IllegalArgumentException(iae.getMessage());
    } catch (Exception e) {
        throw new InternalServerException(e.getMessage());
    }
}
Also used : I_StoredQueryAccess(org.ehrbase.dao.access.interfaces.I_StoredQueryAccess) AqlExpression(org.ehrbase.aql.compiler.AqlExpression) StoredQueryAccess(org.ehrbase.dao.access.jooq.StoredQueryAccess) I_StoredQueryAccess(org.ehrbase.dao.access.interfaces.I_StoredQueryAccess) GeneralRequestProcessingException(org.ehrbase.api.exception.GeneralRequestProcessingException) InternalServerException(org.ehrbase.api.exception.InternalServerException) StructuredString(org.ehrbase.response.ehrscape.StructuredString) GeneralRequestProcessingException(org.ehrbase.api.exception.GeneralRequestProcessingException) BadGatewayException(org.ehrbase.api.exception.BadGatewayException) RestClientException(org.springframework.web.client.RestClientException) DataAccessException(org.jooq.exception.DataAccessException) InternalServerException(org.ehrbase.api.exception.InternalServerException) DataAccessException(org.jooq.exception.DataAccessException)

Aggregations

InternalServerException (org.ehrbase.api.exception.InternalServerException)60 ObjectNotFoundException (org.ehrbase.api.exception.ObjectNotFoundException)19 UUID (java.util.UUID)15 InvalidApiParameterException (org.ehrbase.api.exception.InvalidApiParameterException)15 HttpHeaders (org.springframework.http.HttpHeaders)8 ObjectVersionId (com.nedap.archie.rm.support.identification.ObjectVersionId)7 HashMap (java.util.HashMap)7 StructuredString (org.ehrbase.response.ehrscape.StructuredString)7 DataAccessException (org.jooq.exception.DataAccessException)7 MediaType (org.springframework.http.MediaType)7 Optional (java.util.Optional)6 OriginalVersion (com.nedap.archie.rm.changecontrol.OriginalVersion)5 Timestamp (java.sql.Timestamp)5 Objects (java.util.Objects)5 BadGatewayException (org.ehrbase.api.exception.BadGatewayException)5 GeneralRequestProcessingException (org.ehrbase.api.exception.GeneralRequestProcessingException)5 ResponseEntity (org.springframework.http.ResponseEntity)5 RevisionHistory (com.nedap.archie.rm.generic.RevisionHistory)4 IOException (java.io.IOException)4 LocalDateTime (java.time.LocalDateTime)4