Add implementation, test, and changelog (#3753)

This commit is contained in:
Tadgh 2022-07-04 14:13:18 -07:00 committed by GitHub
parent fb4dce7a53
commit bf851951b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 3 deletions

View File

@ -0,0 +1,4 @@
---
type: fix
issue: 3749
title: "Fixed a regression in 6.0.0 which caused the SearchNarrowingInterceptor to occcasionally be applied to non-search operations."

View File

@ -146,6 +146,11 @@ public class SearchNarrowingInterceptor {
// We don't support this operation type yet // We don't support this operation type yet
Validate.isTrue(theRequestDetails.getRestOperationType() != RestOperationTypeEnum.SEARCH_SYSTEM); Validate.isTrue(theRequestDetails.getRestOperationType() != RestOperationTypeEnum.SEARCH_SYSTEM);
//N.B do not add code above this for filtering, this should only ever occur on search.
if (shouldSkipNarrowing(theRequestDetails)) {
return true;
}
AuthorizedList authorizedList = buildAuthorizedList(theRequestDetails); AuthorizedList authorizedList = buildAuthorizedList(theRequestDetails);
if (authorizedList == null) { if (authorizedList == null) {
return true; return true;
@ -157,9 +162,6 @@ public class SearchNarrowingInterceptor {
postFilteringList.addAll(authorizedList.getAllowedCodeInValueSets()); postFilteringList.addAll(authorizedList.getAllowedCodeInValueSets());
} }
if (theRequestDetails.getRestOperationType() != RestOperationTypeEnum.SEARCH_TYPE) {
return true;
}
FhirContext ctx = theRequestDetails.getServer().getFhirContext(); FhirContext ctx = theRequestDetails.getServer().getFhirContext();
RuntimeResourceDefinition resDef = ctx.getResourceDefinition(theRequestDetails.getResourceName()); RuntimeResourceDefinition resDef = ctx.getResourceDefinition(theRequestDetails.getResourceName());
@ -186,6 +188,15 @@ public class SearchNarrowingInterceptor {
return true; return true;
} }
/**
* Skip unless it is a search request or an $everything operation
*/
private boolean shouldSkipNarrowing(RequestDetails theRequestDetails) {
return theRequestDetails.getRestOperationType() != RestOperationTypeEnum.SEARCH_TYPE
&& !"$everything".equalsIgnoreCase(theRequestDetails.getOperation());
}
@Hook(Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED) @Hook(Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED)
public void hookIncomingRequestPreHandled(ServletRequestDetails theRequestDetails, HttpServletRequest theRequest, HttpServletResponse theResponse) throws AuthenticationException { public void hookIncomingRequestPreHandled(ServletRequestDetails theRequestDetails, HttpServletRequest theRequest, HttpServletResponse theResponse) throws AuthenticationException {
if (theRequestDetails.getRestOperationType() != RestOperationTypeEnum.TRANSACTION) { if (theRequestDetails.getRestOperationType() != RestOperationTypeEnum.TRANSACTION) {

View File

@ -9,6 +9,7 @@ import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.Transaction; import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor; import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
@ -29,6 +30,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Resource; import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.ValueSet; import org.hl7.fhir.r4.model.ValueSet;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
@ -299,6 +301,31 @@ public class SearchNarrowingInterceptorTest {
assertEquals("transaction", ourLastHitMethod); assertEquals("transaction", ourLastHitMethod);
assertEquals("Patient?_id=" + URLEncoder.encode("Patient/123,Patient/456"), ourLastBundleRequest.getUrl()); assertEquals("Patient?_id=" + URLEncoder.encode("Patient/123,Patient/456"), ourLastBundleRequest.getUrl());
} }
@Test
public void testNarrow_OnlyAppliesToSearches() {
ourNextAuthorizedList = new AuthorizedList().addCompartments("Patient/123");
Observation o = new Observation();
o.setSubject(new Reference("Patient/456"));
{
//Create a resource outside of the referenced compartment
Bundle bundle = new Bundle();
bundle.setType(Bundle.BundleType.TRANSACTION);
bundle.addEntry().getRequest().setMethod(Bundle.HTTPVerb.POST).setUrl("Observation");
myClient.transaction().withBundle(bundle).execute();
}
{
Bundle bundle = new Bundle();
bundle.setType(Bundle.BundleType.TRANSACTION);
bundle.addEntry().getRequest().setMethod(Bundle.HTTPVerb.PUT).setUrl("Observation");
//Update a resource outside of the referenced compartment
myClient.transaction().withBundle(bundle).execute();
}
}
@Test @Test
public void testNarrowCompartment_PatientByPatientContext_ClientRequestedNoParams() { public void testNarrowCompartment_PatientByPatientContext_ClientRequestedNoParams() {