diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4601-interceptor-search-history-interaction-support.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4601-interceptor-search-history-interaction-support.yaml new file mode 100644 index 00000000000..fcf58cfb56f --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4601-interceptor-search-history-interaction-support.yaml @@ -0,0 +1,5 @@ +--- +type: fix +issue: 4601 +title: "The InteractionBlockingInterceptor did not have support for the interactions + 'search' and 'history' despite them being declared in the code system. This has been fixed." diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/InteractionBlockingInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/InteractionBlockingInterceptor.java index f33f36d93b5..c82817384be 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/InteractionBlockingInterceptor.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/InteractionBlockingInterceptor.java @@ -202,12 +202,24 @@ public class InteractionBlockingInterceptor { String resourceName = theSpec.substring(0, colonIdx); String interactionName = theSpec.substring(colonIdx + 1); - RestOperationTypeEnum interaction = RestOperationTypeEnum.forCode(interactionName); - Validate.notNull(interaction, "Unknown interaction %s in spec %s", interactionName, theSpec); - addAllowedInteraction(resourceName, interaction); + if (interactionName.equals("search")) { + interactionName = "search-type"; + validateInteraction(interactionName, theSpec, resourceName); + } else if (interactionName.equals("history")) { + validateInteraction("history-instance", theSpec, resourceName); + validateInteraction("history-type", theSpec, resourceName); + } else { + validateInteraction(interactionName, theSpec, resourceName); + } return this; } + private void validateInteraction(String theInteractionName, String theSpec, String theResourceName) { + RestOperationTypeEnum interaction = RestOperationTypeEnum.forCode(theInteractionName); + Validate.notNull(interaction, "Unknown interaction %s in spec %s", theInteractionName, theSpec); + addAllowedInteraction(theResourceName, interaction); + } + /** * Adds an interaction that will be permitted. */ diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/InteractionBlockingInterceptorTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/InteractionBlockingInterceptorTest.java index 8525665e25b..014cab2d84f 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/InteractionBlockingInterceptorTest.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/InteractionBlockingInterceptorTest.java @@ -10,6 +10,7 @@ import ca.uhn.fhir.test.utilities.ITestDataBuilder; import ca.uhn.fhir.test.utilities.server.RestfulServerExtension; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.CapabilityStatement; import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.Observation; @@ -48,6 +49,8 @@ public class InteractionBlockingInterceptorTest implements ITestDataBuilder { // Setup mySvc = new InteractionBlockingInterceptor.Builder(ourCtx) .addAllowedSpec("Patient:read") + .addAllowedSpec("Patient:search") + .addAllowedSpec("Patient:history") .addAllowedSpec("Observation:read") .addAllowedSpec("Observation:create") .build(); @@ -63,11 +66,16 @@ public class InteractionBlockingInterceptorTest implements ITestDataBuilder { "Observation:vread", "OperationDefinition:read", "Patient:read", - "Patient:vread" + "Patient:vread", + "Patient:search-type", + "Patient:history-instance", + "Patient:history-type" )); // Verify Server verifyCreateObservationOk(); + verifySearchObservationOk(); + verifyHistoryObservationOk(); verifyReadObservationOk(); verifyReadEncounterFails(); } @@ -111,6 +119,15 @@ public class InteractionBlockingInterceptorTest implements ITestDataBuilder { myServer.getFhirClient().read().resource("Observation").withId("O0").execute(); } + private void verifySearchObservationOk() { + myServer.getFhirClient().search().forResource("Patient").execute(); + } + + private void verifyHistoryObservationOk() { + myServer.getFhirClient().history().onInstance("Patient/P0").returnBundle(Bundle.class).execute(); + myServer.getFhirClient().history().onType("Patient").returnBundle(Bundle.class).execute(); + } + private void verifyCreateObservationOk() { myServer.getFhirClient().create().resource(new Observation()).execute(); }