diff --git a/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/ConsentInterceptors.java b/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/ConsentInterceptors.java
index 1bb72b5ade5..497952dc5cd 100644
--- a/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/ConsentInterceptors.java
+++ b/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/ConsentInterceptors.java
@@ -58,6 +58,7 @@ public class ConsentInterceptors {
Observation obs = (Observation)theResource;
if (obs.getCategoryFirstRep().hasCoding("http://hl7.org/fhir/codesystem-observation-category.html", "laboratory")) {
return ConsentOutcome.REJECT;
+ //return ConsentOutcome.FORBID;
}
}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java
index 89e6898a0dd..2b7f7c40244 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentInterceptor.java
@@ -165,6 +165,7 @@ public class ConsentInterceptor {
Validate.notNull(outcome, "Consent service returned null outcome");
switch (outcome.getStatus()) {
+ case FORBID:
case REJECT:
throw toForbiddenOperationException(outcome);
case PROCEED:
@@ -243,9 +244,12 @@ public class ConsentInterceptor {
skipSubsequentServices = true;
break;
case REJECT:
+ authorizedResources.put(nextResource, Boolean.FALSE);
thePreResourceAccessDetails.setDontReturnResourceAtIndex(resourceIdx);
skipSubsequentServices = true;
break;
+ case FORBID:
+ throw toForbiddenOperationException(outcome);
}
if (skipSubsequentServices) {
@@ -295,6 +299,7 @@ public class ConsentInterceptor {
thePreResourceShowDetails.setResource(i, newResource);
}
continue;
+ case FORBID:
case REJECT:
if (nextOutcome.getOperationOutcome() != null) {
IBaseOperationOutcome newOperationOutcome = nextOutcome.getOperationOutcome();
@@ -345,6 +350,7 @@ public class ConsentInterceptor {
}
switch (outcome.getStatus()) {
+ case FORBID:
case REJECT:
if (outcome.getOperationOutcome() != null) {
theResource.setResponseResource(outcome.getOperationOutcome());
@@ -393,6 +399,7 @@ public class ConsentInterceptor {
boolean shouldReplaceResource = false;
switch (childOutcome.getStatus()) {
+ case FORBID:
case REJECT:
replacementResource = childOutcome.getOperationOutcome();
shouldReplaceResource = true;
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentOperationStatusEnum.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentOperationStatusEnum.java
index d0baf09ca5a..a9062c182a6 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentOperationStatusEnum.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentOperationStatusEnum.java
@@ -40,4 +40,10 @@ public enum ConsentOperationStatusEnum {
*/
AUTHORIZED,
+ /**
+ * The requested operation cannot proceed, and an operation outcome suitable for
+ * the user is available
+ */
+ FORBID
+
}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentOutcome.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentOutcome.java
index 77cc87a37b1..60bc8e074fc 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentOutcome.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/consent/ConsentOutcome.java
@@ -38,6 +38,11 @@ public class ConsentOutcome {
*/
public static final ConsentOutcome AUTHORIZED = new ConsentOutcome(ConsentOperationStatusEnum.AUTHORIZED);
+ /**
+ * Convenience constant containing new ConsentOutcome(ConsentOperationStatusEnum.FORBID)
+ */
+ public static final ConsentOutcome FORBID = new ConsentOutcome(ConsentOperationStatusEnum.FORBID);
+
private final ConsentOperationStatusEnum myStatus;
private final IBaseOperationOutcome myOperationOutcome;
private final IBaseResource myResource;
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/ConsentInterceptorTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/ConsentInterceptorTest.java
index d472cb2a4a0..d7cc5a2ed42 100644
--- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/ConsentInterceptorTest.java
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/ConsentInterceptorTest.java
@@ -28,8 +28,11 @@ import com.google.common.base.Charsets;
import com.helger.commons.collection.iterate.EmptyEnumeration;
import org.apache.commons.collections4.iterators.IteratorEnumeration;
import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.StringEntity;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Bundle;
@@ -153,6 +156,38 @@ public class ConsentInterceptorTest {
verify(myConsentSvc, timeout(2000).times(0)).completeOperationFailure(any(), any(), any());
}
+ @Test
+ public void testConsentCanSeeResourceForbid() throws IOException {
+ Patient patientA = new Patient();
+ patientA.setId("PT-1-0");
+ patientA.setActive(true);
+ patientA.addName().setFamily("FAMILY").addGiven("GIVEN");
+ patientA.addIdentifier().setSystem("SYSTEM").setValue("VALUEA");
+
+ ourPatientProvider.store(patientA);
+
+ when(myConsentSvc.startOperation(any(), any())).thenReturn(ConsentOutcome.PROCEED);
+ when(myConsentSvc.canSeeResource(any(), any(), any())).thenReturn(ConsentOutcome.FORBID);
+
+ HttpPut httpPut = new HttpPut("http://localhost:" + myPort + "/Patient/PT-1-0");
+ httpPut.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
+
+ httpPut.setEntity(new StringEntity("{\"resourceType\": \"Patient\",\"id\": \"PT-1-0\",\"text\": {\"status\": \"generated\",\"div\": \"
A valid patient resource for testing purposes