From 98c76a4d493c9898e2156c1608f17ac77db86b6d Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Thu, 3 Oct 2019 12:03:38 -0400 Subject: [PATCH] Test passes --- .../main/java/ca/uhn/fhir/util/UrlUtil.java | 21 ++++++ .../util/bundle/ModifiableBundleEntry.java | 6 +- .../uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java | 2 +- .../fhir/jpa/dao/TransactionProcessor.java | 39 +++-------- .../dbcache/DaoSubscriptionProvider.java | 2 - .../fhir/jpa/searchparam/MatchUrlService.java | 20 +----- hapi-fhir-server/pom.xml | 13 ++++ .../auth/SearchNarrowingInterceptor.java | 52 ++++++++++++--- .../servlet}/ServletSubRequestDetails.java | 2 +- .../rest/server/util/ServletRequestUtil.java | 64 +++++++++++++++++++ .../auth/SearchNarrowingInterceptorTest.java | 18 +++--- 11 files changed, 164 insertions(+), 75 deletions(-) rename {hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider => hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/servlet}/ServletSubRequestDetails.java (98%) create mode 100644 hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ServletRequestUtil.java diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/UrlUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/UrlUtil.java index f615f7029a2..f1d2d855bab 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/UrlUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/UrlUtil.java @@ -8,6 +8,8 @@ import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import com.google.common.escape.Escaper; import com.google.common.net.PercentEscaper; +import org.apache.http.NameValuePair; +import org.apache.http.client.utils.URLEncodedUtils; import org.hl7.fhir.instance.model.api.IPrimitiveType; import java.io.UnsupportedEncodingException; @@ -457,4 +459,23 @@ public class UrlUtil { return theString; } + public static List translateMatchUrl(String theMatchUrl) { + List parameters; + String matchUrl = theMatchUrl; + int questionMarkIndex = matchUrl.indexOf('?'); + if (questionMarkIndex != -1) { + matchUrl = matchUrl.substring(questionMarkIndex + 1); + } + matchUrl = matchUrl.replace("|", "%7C"); + matchUrl = matchUrl.replace("=>=", "=%3E%3D"); + matchUrl = matchUrl.replace("=<=", "=%3C%3D"); + matchUrl = matchUrl.replace("=>", "=%3E"); + matchUrl = matchUrl.replace("=<", "=%3C"); + if (matchUrl.contains(" ")) { + throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - URL is invalid (must not contain spaces)"); + } + + parameters = URLEncodedUtils.parse((matchUrl), Constants.CHARSET_UTF8, '&'); + return parameters; + } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/bundle/ModifiableBundleEntry.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/bundle/ModifiableBundleEntry.java index e717f13e116..1cd20db8164 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/bundle/ModifiableBundleEntry.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/bundle/ModifiableBundleEntry.java @@ -20,13 +20,11 @@ public class ModifiableBundleEntry { return myBundleEntryParts; } - void setRequestUrl(FhirContext theFhirContext, String theRequestUrl) { + public void setRequestUrl(FhirContext theFhirContext, String theRequestUrl) { myBundleEntryMutator.setRequestUrl(theFhirContext, theRequestUrl); } - String getRequestUrl() { + public String getRequestUrl() { return myBundleEntryParts.getUrl(); } - - } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java index 09aa5776d28..34d98c5de73 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java @@ -24,7 +24,7 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.jpa.delete.DeleteConflictList; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.TagDefinition; -import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails; +import ca.uhn.fhir.rest.server.servlet.ServletSubRequestDetails; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/TransactionProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/TransactionProcessor.java index c0a5274fe8c..0c908111a9e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/TransactionProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/TransactionProcessor.java @@ -30,7 +30,7 @@ import ca.uhn.fhir.jpa.delete.DeleteConflictList; import ca.uhn.fhir.jpa.delete.DeleteConflictService; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage; -import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails; +import ca.uhn.fhir.rest.server.servlet.ServletSubRequestDetails; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.util.DeleteConflict; import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster; @@ -49,11 +49,11 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.method.BaseMethodBinding; import ca.uhn.fhir.rest.server.method.BaseResourceReturningMethodBinding; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; +import ca.uhn.fhir.rest.server.util.ServletRequestUtil; import ca.uhn.fhir.util.*; import com.google.common.base.Charsets; import com.google.common.collect.ArrayListMultimap; import org.apache.commons.lang3.Validate; -import org.apache.http.NameValuePair; import org.hibernate.Session; import org.hibernate.internal.SessionImpl; import org.hl7.fhir.dstu3.model.Bundle; @@ -402,37 +402,14 @@ public class TransactionProcessor { Integer originalOrder = originalRequestOrder.get(nextReqEntry); BUNDLEENTRY nextRespEntry = myVersionAdapter.getEntries(response).get(originalOrder); - ServletSubRequestDetails requestDetails = new ServletSubRequestDetails(theRequestDetails); - requestDetails.setServletRequest(theRequestDetails.getServletRequest()); - requestDetails.setRequestType(RequestTypeEnum.GET); - requestDetails.setServer(theRequestDetails.getServer()); - - String url = extractTransactionUrlOrThrowException(nextReqEntry, "GET"); - - int qIndex = url.indexOf('?'); ArrayListMultimap paramValues = ArrayListMultimap.create(); - requestDetails.setParameters(new HashMap<>()); - if (qIndex != -1) { - String params = url.substring(qIndex); - List parameters = myMatchUrlService.translateMatchUrl(params); - for (NameValuePair next : parameters) { - paramValues.put(next.getName(), next.getValue()); - } - for (Map.Entry> nextParamEntry : paramValues.asMap().entrySet()) { - String[] nextValue = nextParamEntry.getValue().toArray(new String[nextParamEntry.getValue().size()]); - requestDetails.addParameter(nextParamEntry.getKey(), nextValue); - } - url = url.substring(0, qIndex); - } - if (url.length() > 0 && url.charAt(0) == '/') { - url = url.substring(1); - } + String transactionUrl = extractTransactionUrlOrThrowException(nextReqEntry, "GET"); - requestDetails.setRequestPath(url); - requestDetails.setFhirServerBase(theRequestDetails.getFhirServerBase()); + ServletSubRequestDetails requestDetails = ServletRequestUtil.getServletSubRequestDetails(theRequestDetails, transactionUrl, paramValues); + + String url = requestDetails.getRequestPath(); - theRequestDetails.getServer().populateRequestDetailsFromRequestPath(requestDetails, url); BaseMethodBinding method = theRequestDetails.getServer().determineResourceMethod(requestDetails, url); if (method == null) { throw new IllegalArgumentException("Unable to handle GET " + url); @@ -463,7 +440,7 @@ public class TransactionProcessor { } catch (NotModifiedException e) { myVersionAdapter.setResponseStatus(nextRespEntry, toStatusString(Constants.STATUS_HTTP_304_NOT_MODIFIED)); } catch (BaseServerResponseException e) { - ourLog.info("Failure processing transaction GET {}: {}", url, e.toString()); + ourLog.info("Failure processing transaction GET {}: {}", requestDetails.getRequestPath(), e.toString()); myVersionAdapter.setResponseStatus(nextRespEntry, toStatusString(e.getStatusCode())); populateEntryWithOperationOutcome(e, nextRespEntry); } @@ -486,6 +463,8 @@ public class TransactionProcessor { return response; } + + private boolean isValidVerb(String theVerb) { try { return org.hl7.fhir.r4.model.Bundle.HTTPVerb.fromCode(theVerb) != null; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/dbcache/DaoSubscriptionProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/dbcache/DaoSubscriptionProvider.java index 569f784ab54..adc49ef21d3 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/dbcache/DaoSubscriptionProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/dbcache/DaoSubscriptionProvider.java @@ -22,12 +22,10 @@ package ca.uhn.fhir.jpa.subscription.dbcache; import ca.uhn.fhir.jpa.dao.DaoRegistry; import ca.uhn.fhir.jpa.dao.IFhirResourceDao; -import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.subscription.SubscriptionActivatingInterceptor; import ca.uhn.fhir.jpa.subscription.module.cache.ISubscriptionProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider; -import ca.uhn.fhir.rest.api.server.RequestDetails; import org.hl7.fhir.instance.model.api.IBaseResource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java index e6bfda3df67..be810cca188 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java @@ -34,9 +34,9 @@ import ca.uhn.fhir.rest.param.ParameterUtil; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.util.CoverageIgnore; +import ca.uhn.fhir.util.UrlUtil; import com.google.common.collect.ArrayListMultimap; import org.apache.http.NameValuePair; -import org.apache.http.client.utils.URLEncodedUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -138,23 +138,7 @@ public class MatchUrlService { } public List translateMatchUrl(String theMatchUrl) { - List parameters; - String matchUrl = theMatchUrl; - int questionMarkIndex = matchUrl.indexOf('?'); - if (questionMarkIndex != -1) { - matchUrl = matchUrl.substring(questionMarkIndex + 1); - } - matchUrl = matchUrl.replace("|", "%7C"); - matchUrl = matchUrl.replace("=>=", "=%3E%3D"); - matchUrl = matchUrl.replace("=<=", "=%3C%3D"); - matchUrl = matchUrl.replace("=>", "=%3E"); - matchUrl = matchUrl.replace("=<", "=%3C"); - if (matchUrl.contains(" ")) { - throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - URL is invalid (must not contain spaces)"); - } - - parameters = URLEncodedUtils.parse((matchUrl), Constants.CHARSET_UTF8, '&'); - return parameters; + return UrlUtil.translateMatchUrl(theMatchUrl); } @CoverageIgnore diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml index 377657b5ef9..df65a7f53b6 100644 --- a/hapi-fhir-server/pom.xml +++ b/hapi-fhir-server/pom.xml @@ -31,6 +31,19 @@ javax.servlet-api provided + + + org.apache.jena + apache-jena-libs + true + pom + + + com.github.jsonld-java + jsonld-java + + +