Merge pull request #2650 from hapifhir/issue-2648-consent-interceptor-metadata

Prevent consent interceptor from running on metadata
This commit is contained in:
Tadgh 2021-05-11 13:18:50 -04:00 committed by GitHub
commit 1fe51d1ca2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 93 additions and 147 deletions

View File

@ -82,6 +82,10 @@ public class FhirServerConfigCommon {
logger.error("----FhiServerConfigCommon: getDataSource: setting driver error: " + e.getMessage()); logger.error("----FhiServerConfigCommon: getDataSource: setting driver error: " + e.getMessage());
} }
dataSource.setUrl(dbUrl); dataSource.setUrl(dbUrl);
// A check for WS-2020-0287
assert dataSource.getJmxName() == null;
return dataSource; return dataSource;
} }

View File

@ -0,0 +1,4 @@
---
type: change
issue: 2648
title: "The ConsentInterceptor no longer fully runs on calls to `/metadata` or during the `$meta` operation."

View File

@ -61,7 +61,7 @@ import org.springframework.beans.factory.annotation.Required;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Date; import java.util.Date;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META; import static ca.uhn.fhir.rest.server.provider.ProviderConstants.OPERATION_META;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_ADD; import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_ADD;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE; import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE;

View File

@ -21,37 +21,7 @@ package ca.uhn.fhir.jpa.provider;
*/ */
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.resource.Parameters;
import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IIdType;
import javax.servlet.http.HttpServletRequest;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_ADD;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE;
public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResourceProvider<T> { public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResourceProvider<T> {

View File

@ -14,6 +14,7 @@ import ca.uhn.fhir.rest.annotation.OperationParam;
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.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.r4.model.IntegerType; import org.hl7.fhir.r4.model.IntegerType;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -163,7 +164,7 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
return retVal; return retVal;
} }
@Operation(name = JpaConstants.OPERATION_META, idempotent = true, returnParameters = { @Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = MetaDt.class) @OperationParam(name = "return", type = MetaDt.class)
}) })
public Parameters meta(RequestDetails theRequestDetails) { public Parameters meta(RequestDetails theRequestDetails) {

View File

@ -21,37 +21,9 @@ package ca.uhn.fhir.jpa.provider.dstu3;
*/ */
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider; import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.IntegerType;
import org.hl7.fhir.dstu3.model.Meta;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import javax.servlet.http.HttpServletRequest;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_ADD;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE;
import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters; import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaResourceProvider<T> { public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaResourceProvider<T> {

View File

@ -1,42 +1,29 @@
package ca.uhn.fhir.jpa.provider.dstu3; package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus; import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.OperationParam;
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.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.DecimalType;
import org.hl7.fhir.dstu3.model.IntegerType; import org.hl7.fhir.dstu3.model.IntegerType;
import org.hl7.fhir.dstu3.model.Meta; import org.hl7.fhir.dstu3.model.Meta;
import org.hl7.fhir.dstu3.model.Parameters; import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.TreeMap; import java.util.TreeMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters; import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
/* /*
@ -174,7 +161,7 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
return retVal; return retVal;
} }
@Operation(name = JpaConstants.OPERATION_META, idempotent = true, returnParameters = { @Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class) @OperationParam(name = "return", type = Meta.class)
}) })
public Parameters meta(RequestDetails theRequestDetails) { public Parameters meta(RequestDetails theRequestDetails) {

View File

@ -21,35 +21,8 @@ package ca.uhn.fhir.jpa.provider.r4;
*/ */
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider; import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.IntegerType;
import org.hl7.fhir.r4.model.Meta;
import org.hl7.fhir.r4.model.Parameters;
import javax.servlet.http.HttpServletRequest;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_ADD;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE;
public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResourceProvider<T> { public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResourceProvider<T> {

View File

@ -9,6 +9,7 @@ import ca.uhn.fhir.rest.annotation.OperationParam;
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.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.IntegerType; import org.hl7.fhir.r4.model.IntegerType;
@ -159,7 +160,7 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle,
return retVal; return retVal;
} }
@Operation(name = JpaConstants.OPERATION_META, idempotent = true, returnParameters = { @Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class) @OperationParam(name = "return", type = Meta.class)
}) })
public Parameters meta(RequestDetails theRequestDetails) { public Parameters meta(RequestDetails theRequestDetails) {

View File

@ -21,35 +21,8 @@ package ca.uhn.fhir.jpa.provider.r5;
*/ */
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider; import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.IdType;
import org.hl7.fhir.r5.model.IntegerType;
import org.hl7.fhir.r5.model.Meta;
import org.hl7.fhir.r5.model.Parameters;
import javax.servlet.http.HttpServletRequest;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_ADD;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE;
public class JpaResourceProviderR5<T extends IAnyResource> extends BaseJpaResourceProvider<T> { public class JpaResourceProviderR5<T extends IAnyResource> extends BaseJpaResourceProvider<T> {

View File

@ -1,40 +1,29 @@
package ca.uhn.fhir.jpa.provider.r5; package ca.uhn.fhir.jpa.provider.r5;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus; import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.OperationParam;
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.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.Bundle; import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.DecimalType;
import org.hl7.fhir.r5.model.IntegerType; import org.hl7.fhir.r5.model.IntegerType;
import org.hl7.fhir.r5.model.Meta; import org.hl7.fhir.r5.model.Meta;
import org.hl7.fhir.r5.model.Parameters; import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r5.model.StringType;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.TreeMap; import java.util.TreeMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.apache.commons.lang3.StringUtils.isBlank;
/* /*
* #%L * #%L
@ -171,7 +160,7 @@ public class JpaSystemProviderR5 extends BaseJpaSystemProviderDstu2Plus<Bundle,
return retVal; return retVal;
} }
@Operation(name = JpaConstants.OPERATION_META, idempotent = true, returnParameters = { @Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class) @OperationParam(name = "return", type = Meta.class)
}) })
public Parameters meta(RequestDetails theRequestDetails) { public Parameters meta(RequestDetails theRequestDetails) {

View File

@ -122,6 +122,9 @@ public enum DriverTypeEnum {
dataSource.setUsername(theUsername); dataSource.setUsername(theUsername);
dataSource.setPassword(thePassword); dataSource.setPassword(thePassword);
// A check for WS-2020-0287
assert dataSource.getJmxName() == null;
return newConnectionProperties(dataSource); return newConnectionProperties(dataSource);
} }

View File

@ -93,10 +93,6 @@ public class JpaConstants {
* Operation name for the $get-resource-counts operation * Operation name for the $get-resource-counts operation
*/ */
public static final String OPERATION_GET_RESOURCE_COUNTS = "$get-resource-counts"; public static final String OPERATION_GET_RESOURCE_COUNTS = "$get-resource-counts";
/**
* Operation name for the $meta operation
*/
public static final String OPERATION_META = "$meta";
/** /**
* Operation name for the $validate operation * Operation name for the $validate operation
*/ */

View File

@ -44,6 +44,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import static ca.uhn.fhir.rest.api.Constants.URL_TOKEN_METADATA;
import static ca.uhn.fhir.rest.server.provider.ProviderConstants.OPERATION_META;
@Interceptor @Interceptor
public class ConsentInterceptor { public class ConsentInterceptor {
private static final AtomicInteger ourInstanceCount = new AtomicInteger(0); private static final AtomicInteger ourInstanceCount = new AtomicInteger(0);
@ -94,6 +97,9 @@ public class ConsentInterceptor {
@Hook(value = Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED) @Hook(value = Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED)
public void interceptPreHandled(RequestDetails theRequestDetails) { public void interceptPreHandled(RequestDetails theRequestDetails) {
if (isAllowListedRequest(theRequestDetails)) {
return;
}
ConsentOutcome outcome = myConsentService.startOperation(theRequestDetails, myContextConsentServices); ConsentOutcome outcome = myConsentService.startOperation(theRequestDetails, myContextConsentServices);
Validate.notNull(outcome, "Consent service returned null outcome"); Validate.notNull(outcome, "Consent service returned null outcome");
@ -129,6 +135,9 @@ public class ConsentInterceptor {
if (isRequestAuthorized(theRequestDetails)) { if (isRequestAuthorized(theRequestDetails)) {
return; return;
} }
if (isAllowListedRequest(theRequestDetails)) {
return;
}
for (int i = 0; i < thePreResourceAccessDetails.size(); i++) { for (int i = 0; i < thePreResourceAccessDetails.size(); i++) {
IBaseResource nextResource = thePreResourceAccessDetails.getResource(i); IBaseResource nextResource = thePreResourceAccessDetails.getResource(i);
@ -150,6 +159,9 @@ public class ConsentInterceptor {
if (isRequestAuthorized(theRequestDetails)) { if (isRequestAuthorized(theRequestDetails)) {
return; return;
} }
if (isAllowListedRequest(theRequestDetails)) {
return;
}
IdentityHashMap<IBaseResource, Boolean> alreadySeenResources = getAlreadySeenResourcesMap(theRequestDetails); IdentityHashMap<IBaseResource, Boolean> alreadySeenResources = getAlreadySeenResourcesMap(theRequestDetails);
for (int i = 0; i < thePreResourceShowDetails.size(); i++) { for (int i = 0; i < thePreResourceShowDetails.size(); i++) {
@ -198,6 +210,9 @@ public class ConsentInterceptor {
if (isRequestAuthorized(theRequestDetails)) { if (isRequestAuthorized(theRequestDetails)) {
return; return;
} }
if (isAllowListedRequest(theRequestDetails)) {
return;
}
IdentityHashMap<IBaseResource, Boolean> alreadySeenResources = getAlreadySeenResourcesMap(theRequestDetails); IdentityHashMap<IBaseResource, Boolean> alreadySeenResources = getAlreadySeenResourcesMap(theRequestDetails);
@ -330,4 +345,16 @@ public class ConsentInterceptor {
} }
return new ForbiddenOperationException("Rejected by consent service", operationOutcome); return new ForbiddenOperationException("Rejected by consent service", operationOutcome);
} }
private boolean isAllowListedRequest(RequestDetails theRequestDetails) {
return isMetadataPath(theRequestDetails) || isMetaOperation(theRequestDetails);
}
private boolean isMetaOperation(RequestDetails theRequestDetails) {
return OPERATION_META.equals(theRequestDetails.getOperation());
}
private boolean isMetadataPath(RequestDetails theRequestDetails) {
return URL_TOKEN_METADATA.equals(theRequestDetails.getRequestPath());
}
} }

View File

@ -97,4 +97,8 @@ public class ProviderConstants {
*/ */
public static final String CQL_EVALUATE_MEASURE = "$evaluate-measure"; public static final String CQL_EVALUATE_MEASURE = "$evaluate-measure";
/**
* Operation name for the $meta operation
* */
public static final String OPERATION_META = "$meta";
} }

View File

@ -2,6 +2,8 @@ package ca.uhn.fhir.rest.server.interceptor;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.api.BundleInclusionRule; import ca.uhn.fhir.context.api.BundleInclusionRule;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.RequiredParam; import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
@ -11,11 +13,13 @@ import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider; import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.interceptor.auth.SearchNarrowingInterceptorTest;
import ca.uhn.fhir.rest.server.interceptor.consent.ConsentInterceptor; import ca.uhn.fhir.rest.server.interceptor.consent.ConsentInterceptor;
import ca.uhn.fhir.rest.server.interceptor.consent.ConsentOperationStatusEnum; import ca.uhn.fhir.rest.server.interceptor.consent.ConsentOperationStatusEnum;
import ca.uhn.fhir.rest.server.interceptor.consent.ConsentOutcome; import ca.uhn.fhir.rest.server.interceptor.consent.ConsentOutcome;
import ca.uhn.fhir.rest.server.interceptor.consent.IConsentService; import ca.uhn.fhir.rest.server.interceptor.consent.IConsentService;
import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider; import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.test.utilities.JettyUtil; import ca.uhn.fhir.test.utilities.JettyUtil;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
@ -27,9 +31,11 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource; 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.OperationOutcome; import org.hl7.fhir.r4.model.OperationOutcome;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
@ -70,6 +76,7 @@ public class ConsentInterceptorTest {
private static Server ourServer; private static Server ourServer;
private static DummyPatientResourceProvider ourPatientProvider; private static DummyPatientResourceProvider ourPatientProvider;
private static IGenericClient ourFhirClient; private static IGenericClient ourFhirClient;
private static DummySystemProvider ourSystemProvider;
@Mock @Mock
private IConsentService myConsentSvc; private IConsentService myConsentSvc;
@ -163,6 +170,28 @@ public class ConsentInterceptorTest {
} }
@Test
public void testMetadataCallHasChecksSkipped() throws IOException{
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/metadata");
try (CloseableHttpResponse status = ourClient.execute(httpGet)) {
assertEquals(200, status.getStatusLine().getStatusCode());
String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8);
ourLog.info("Response: {}", responseContent);
}
httpGet = new HttpGet("http://localhost:" + ourPort + "/$meta");
try (CloseableHttpResponse status = ourClient.execute(httpGet)) {
assertEquals(200, status.getStatusLine().getStatusCode());
String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8);
ourLog.info("Response: {}", responseContent);
}
verify(myConsentSvc, times(0)).canSeeResource(any(), any(), any());
verify(myConsentSvc, times(0)).willSeeResource(any(), any(), any());
verify(myConsentSvc, times(0)).startOperation(any(), any());
verify(myConsentSvc, times(2)).completeOperationSuccess(any(), any());
}
@Test @Test
public void testSearch_SeeResourceAuthorizesOuterBundle() throws IOException { public void testSearch_SeeResourceAuthorizesOuterBundle() throws IOException {
ourPatientProvider.store((Patient) new Patient().setActive(true).setId("PTA")); ourPatientProvider.store((Patient) new Patient().setActive(true).setId("PTA"));
@ -457,11 +486,13 @@ public class ConsentInterceptorTest {
ourServer = new Server(0); ourServer = new Server(0);
ourPatientProvider = new DummyPatientResourceProvider(ourCtx); ourPatientProvider = new DummyPatientResourceProvider(ourCtx);
ourSystemProvider = new DummySystemProvider();
ServletHandler servletHandler = new ServletHandler(); ServletHandler servletHandler = new ServletHandler();
ourServlet = new RestfulServer(ourCtx); ourServlet = new RestfulServer(ourCtx);
ourServlet.setDefaultPrettyPrint(true); ourServlet.setDefaultPrettyPrint(true);
ourServlet.setResourceProviders(ourPatientProvider); ourServlet.setResourceProviders(ourPatientProvider);
ourServlet.registerProvider(ourSystemProvider);
ourServlet.setBundleInclusionRule(BundleInclusionRule.BASED_ON_RESOURCE_PRESENCE); ourServlet.setBundleInclusionRule(BundleInclusionRule.BASED_ON_RESOURCE_PRESENCE);
ServletHolder servletHolder = new ServletHolder(ourServlet); ServletHolder servletHolder = new ServletHolder(ourServlet);
servletHandler.addServletWithMapping(servletHolder, "/*"); servletHandler.addServletWithMapping(servletHolder, "/*");
@ -478,4 +509,15 @@ public class ConsentInterceptorTest {
ourFhirClient = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort); ourFhirClient = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort);
} }
private static class DummySystemProvider{
@Operation(name = "$meta", idempotent = true, returnParameters = {
@OperationParam(name = "return", typeName = "Meta")
})
public IBaseParameters meta(ServletRequestDetails theRequestDetails) {
Parameters retval = new Parameters();
retval.addParameter("Meta", "Yes");
return retval;
}
}
} }