();
@@ -127,63 +128,63 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter
private OperationExamineDirection determineOperationDirection(RestOperationTypeEnum theOperation, IBaseResource theRequestResource) {
switch (theOperation) {
- case ADD_TAGS:
- case DELETE_TAGS:
- case GET_TAGS:
- // These are DSTU1 operations and not relevant
- return OperationExamineDirection.NONE;
+ case ADD_TAGS:
+ case DELETE_TAGS:
+ case GET_TAGS:
+ // These are DSTU1 operations and not relevant
+ return OperationExamineDirection.NONE;
- case EXTENDED_OPERATION_INSTANCE:
- case EXTENDED_OPERATION_SERVER:
- case EXTENDED_OPERATION_TYPE:
- return OperationExamineDirection.BOTH;
+ case EXTENDED_OPERATION_INSTANCE:
+ case EXTENDED_OPERATION_SERVER:
+ case EXTENDED_OPERATION_TYPE:
+ return OperationExamineDirection.BOTH;
- case METADATA:
- // Security does not apply to these operations
- return OperationExamineDirection.IN;
+ case METADATA:
+ // Security does not apply to these operations
+ return OperationExamineDirection.IN;
- case DELETE:
- // Delete is a special case
- return OperationExamineDirection.NONE;
+ case DELETE:
+ // Delete is a special case
+ return OperationExamineDirection.NONE;
- case CREATE:
- case UPDATE:
- case PATCH:
- // if (theRequestResource != null) {
- // if (theRequestResource.getIdElement() != null) {
- // if (theRequestResource.getIdElement().hasIdPart() == false) {
- // return OperationExamineDirection.IN_UNCATEGORIZED;
- // }
- // }
- // }
- return OperationExamineDirection.IN;
+ case CREATE:
+ case UPDATE:
+ case PATCH:
+ // if (theRequestResource != null) {
+ // if (theRequestResource.getIdElement() != null) {
+ // if (theRequestResource.getIdElement().hasIdPart() == false) {
+ // return OperationExamineDirection.IN_UNCATEGORIZED;
+ // }
+ // }
+ // }
+ return OperationExamineDirection.IN;
- case META:
- case META_ADD:
- case META_DELETE:
- // meta operations do not apply yet
- return OperationExamineDirection.NONE;
+ case META:
+ case META_ADD:
+ case META_DELETE:
+ // meta operations do not apply yet
+ return OperationExamineDirection.NONE;
- case GET_PAGE:
- case HISTORY_INSTANCE:
- case HISTORY_SYSTEM:
- case HISTORY_TYPE:
- case READ:
- case SEARCH_SYSTEM:
- case SEARCH_TYPE:
- case VREAD:
- return OperationExamineDirection.OUT;
+ case GET_PAGE:
+ case HISTORY_INSTANCE:
+ case HISTORY_SYSTEM:
+ case HISTORY_TYPE:
+ case READ:
+ case SEARCH_SYSTEM:
+ case SEARCH_TYPE:
+ case VREAD:
+ return OperationExamineDirection.OUT;
- case TRANSACTION:
- return OperationExamineDirection.BOTH;
+ case TRANSACTION:
+ return OperationExamineDirection.BOTH;
- case VALIDATE:
- // Nothing yet
- return OperationExamineDirection.NONE;
+ case VALIDATE:
+ // Nothing yet
+ return OperationExamineDirection.NONE;
- default:
- // Should not happen
- throw new IllegalStateException("Unable to apply security to event of type " + theOperation);
+ default:
+ // Should not happen
+ throw new IllegalStateException("Unable to apply security to event of type " + theOperation);
}
}
@@ -195,6 +196,16 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter
return myDefaultPolicy;
}
+ /**
+ * The default policy if no rules have been found to apply. Default value for this setting is {@link PolicyEnum#DENY}
+ *
+ * @param theDefaultPolicy The policy (must not be null
)
+ */
+ public void setDefaultPolicy(PolicyEnum theDefaultPolicy) {
+ Validate.notNull(theDefaultPolicy, "theDefaultPolicy must not be null");
+ myDefaultPolicy = theDefaultPolicy;
+ }
+
/**
* Handle an access control verdict of {@link PolicyEnum#DENY}.
*
@@ -221,17 +232,17 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter
IIdType inputResourceId = null;
switch (determineOperationDirection(theOperation, theProcessedRequest.getResource())) {
- case IN:
- case BOTH:
- inputResource = theProcessedRequest.getResource();
- inputResourceId = theProcessedRequest.getId();
- break;
- case OUT:
- // inputResource = null;
- inputResourceId = theProcessedRequest.getId();
- break;
- case NONE:
- return;
+ case IN:
+ case BOTH:
+ inputResource = theProcessedRequest.getResource();
+ inputResourceId = theProcessedRequest.getId();
+ break;
+ case OUT:
+ // inputResource = null;
+ inputResourceId = theProcessedRequest.getId();
+ break;
+ case NONE:
+ return;
}
RequestDetails requestDetails = theProcessedRequest.getRequestDetails();
@@ -241,43 +252,39 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter
@Override
public boolean outgoingResponse(RequestDetails theRequestDetails, IBaseResource theResponseObject) {
switch (determineOperationDirection(theRequestDetails.getRestOperationType(), null)) {
- case IN:
- case NONE:
- return true;
- case BOTH:
- case OUT:
- break;
+ case IN:
+ case NONE:
+ return true;
+ case BOTH:
+ case OUT:
+ break;
}
FhirContext fhirContext = theRequestDetails.getServer().getFhirContext();
List resources = Collections.emptyList();
switch (theRequestDetails.getRestOperationType()) {
- case SEARCH_SYSTEM:
- case SEARCH_TYPE:
- case HISTORY_INSTANCE:
- case HISTORY_SYSTEM:
- case HISTORY_TYPE:
- case TRANSACTION:
- case GET_PAGE:
- case EXTENDED_OPERATION_SERVER:
- case EXTENDED_OPERATION_TYPE:
- case EXTENDED_OPERATION_INSTANCE: {
- if (theResponseObject != null) {
- if (theResponseObject instanceof IBaseBundle) {
- resources = toListOfResourcesAndExcludeContainer(theResponseObject, fhirContext);
- } else if (theResponseObject instanceof IBaseParameters) {
+ case SEARCH_SYSTEM:
+ case SEARCH_TYPE:
+ case HISTORY_INSTANCE:
+ case HISTORY_SYSTEM:
+ case HISTORY_TYPE:
+ case TRANSACTION:
+ case GET_PAGE:
+ case EXTENDED_OPERATION_SERVER:
+ case EXTENDED_OPERATION_TYPE:
+ case EXTENDED_OPERATION_INSTANCE: {
+ if (theResponseObject != null) {
resources = toListOfResourcesAndExcludeContainer(theResponseObject, fhirContext);
}
+ break;
}
- break;
- }
- default: {
- if (theResponseObject != null) {
- resources = Collections.singletonList(theResponseObject);
+ default: {
+ if (theResponseObject != null) {
+ resources = Collections.singletonList(theResponseObject);
+ }
+ break;
}
- break;
- }
}
for (IBaseResource nextResponse : resources) {
@@ -296,7 +303,7 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter
@CoverageIgnore
@Override
public boolean outgoingResponse(RequestDetails theRequestDetails, TagList theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
- throws AuthenticationException {
+ throws AuthenticationException {
throw failForDstu1();
}
@@ -318,33 +325,38 @@ public class AuthorizationInterceptor extends ServerOperationInterceptorAdapter
handleUserOperation(theRequest, theNewResource, RestOperationTypeEnum.UPDATE);
}
- /**
- * The default policy if no rules have been found to apply. Default value for this setting is {@link PolicyEnum#DENY}
- *
- * @param theDefaultPolicy
- * The policy (must not be null
)
- */
- public void setDefaultPolicy(PolicyEnum theDefaultPolicy) {
- Validate.notNull(theDefaultPolicy, "theDefaultPolicy must not be null");
- myDefaultPolicy = theDefaultPolicy;
- }
-
- private List toListOfResourcesAndExcludeContainer(IBaseResource theResponseObject, FhirContext fhirContext) {
- List resources;
- resources = fhirContext.newTerser().getAllPopulatedChildElementsOfType(theResponseObject, IBaseResource.class);
-
- // Exclude the container
- if (resources.size() > 0 && resources.get(0) == theResponseObject) {
- resources = resources.subList(1, resources.size());
- }
-
- return resources;
- }
-
private static UnsupportedOperationException failForDstu1() {
return new UnsupportedOperationException("Use of this interceptor on DSTU1 servers is not supportd");
}
+ static List toListOfResourcesAndExcludeContainer(IBaseResource theResponseObject, FhirContext fhirContext) {
+ if (theResponseObject == null) {
+ return Collections.emptyList();
+ }
+
+ List retVal;
+
+ boolean isContainer = false;
+ if (theResponseObject instanceof IBaseBundle) {
+ isContainer = true;
+ } else if (theResponseObject instanceof IBaseParameters) {
+ isContainer = true;
+ }
+
+ if (!isContainer) {
+ return Collections.singletonList(theResponseObject);
+ }
+
+ retVal = fhirContext.newTerser().getAllPopulatedChildElementsOfType(theResponseObject, IBaseResource.class);
+
+ // Exclude the container
+ if (retVal.size() > 0 && retVal.get(0) == theResponseObject) {
+ retVal = retVal.subList(1, retVal.size());
+ }
+
+ return retVal;
+ }
+
private enum OperationExamineDirection {
BOTH,
IN,
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleImplOp.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleImplOp.java
index a8b8e113053..1d9fb8c838a 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleImplOp.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleImplOp.java
@@ -165,13 +165,15 @@ class RuleImplOp extends BaseRule /* implements IAuthRule */ {
}
return verdict;
} else if (theOutputResource != null) {
- List inputResources = BundleUtil.toListOfEntries(ctx, (IBaseBundle) theInputResource);
+
+ List outputResources = AuthorizationInterceptor.toListOfResourcesAndExcludeContainer(theOutputResource, theRequestDetails.getFhirContext());
+
Verdict verdict = null;
- for (BundleEntryParts nextPart : inputResources) {
- if (nextPart.getResource() == null) {
+ for (IBaseResource nextResource : outputResources) {
+ if (nextResource == null) {
continue;
}
- Verdict newVerdict = theRuleApplier.applyRulesAndReturnDecision(RestOperationTypeEnum.READ, theRequestDetails, null, null, nextPart.getResource());
+ Verdict newVerdict = theRuleApplier.applyRulesAndReturnDecision(RestOperationTypeEnum.READ, theRequestDetails, null, null, nextResource);
if (newVerdict == null) {
continue;
} else if (verdict == null) {
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/AuthorizationInterceptorR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/AuthorizationInterceptorR4Test.java
index 8e633ee2417..86944b35191 100644
--- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/AuthorizationInterceptorR4Test.java
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/AuthorizationInterceptorR4Test.java
@@ -52,11 +52,11 @@ import static org.junit.Assert.*;
public class AuthorizationInterceptorR4Test {
private static final String ERR403 = "{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"severity\":\"error\",\"code\":\"processing\",\"diagnostics\":\"Access denied by default policy (no applicable rules)\"}]}";
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(AuthorizationInterceptorR4Test.class);
private static CloseableHttpClient ourClient;
private static String ourConditionalCreateId;
private static FhirContext ourCtx = FhirContext.forR4();
private static boolean ourHitMethod;
- private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(AuthorizationInterceptorR4Test.class);
private static int ourPort;
private static List ourReturn;
private static Server ourServer;
@@ -112,6 +112,77 @@ public class AuthorizationInterceptorR4Test {
return retVal;
}
+ private Bundle createTransactionWithPlaceholdersRequestBundle() {
+ // Create a input that will be used as a transaction
+ Bundle input = new Bundle();
+ input.setType(Bundle.BundleType.TRANSACTION);
+
+ String encounterId = "123-123";
+ String encounterSystem = "http://our.internal.code.system/encounter";
+ Encounter encounter = new Encounter();
+
+ encounter.addIdentifier(new Identifier().setValue(encounterId)
+ .setSystem(encounterSystem));
+
+ encounter.setStatus(Encounter.EncounterStatus.FINISHED);
+
+ Patient p = new Patient()
+ .addIdentifier(new Identifier().setValue("321-321").setSystem("http://our.internal.code.system/patient"));
+ p.setId(IdDt.newRandomUuid());
+
+ // add patient to input so its created
+ input.addEntry()
+ .setFullUrl(p.getId())
+ .setResource(p)
+ .getRequest()
+ .setUrl("Patient")
+ .setMethod(Bundle.HTTPVerb.POST);
+
+ Reference patientRef = new Reference(p.getId());
+
+ encounter.setSubject(patientRef);
+ Condition condition = new Condition()
+ .setCode(new CodeableConcept().addCoding(
+ new Coding("http://hl7.org/fhir/icd-10", "S53.40", "FOREARM SPRAIN / STRAIN")))
+ .setSubject(patientRef);
+
+ condition.setId(IdDt.newRandomUuid());
+
+ // add condition to input so its created
+ input.addEntry()
+ .setFullUrl(condition.getId())
+ .setResource(condition)
+ .getRequest()
+ .setUrl("Condition")
+ .setMethod(Bundle.HTTPVerb.POST);
+
+ Encounter.DiagnosisComponent dc = new Encounter.DiagnosisComponent();
+
+ dc.setCondition(new Reference(condition.getId()));
+ encounter.addDiagnosis(dc);
+ CodeableConcept reason = new CodeableConcept();
+ reason.setText("SLIPPED ON FLOOR,PAIN L) ELBOW");
+ encounter.addReason(reason);
+
+ // add encounter to input so its created
+ input.addEntry()
+ .setResource(encounter)
+ .getRequest()
+ .setUrl("Encounter")
+ .setIfNoneExist("identifier=" + encounterSystem + "|" + encounterId)
+ .setMethod(Bundle.HTTPVerb.POST);
+ return input;
+ }
+
+ private Bundle createTransactionWithPlaceholdersResponseBundle() {
+ Bundle output = new Bundle();
+ output.setType(Bundle.BundleType.TRANSACTIONRESPONSE);
+ output.addEntry()
+ .setResource(new Patient().setActive(true)) // don't give this an ID
+ .getResponse().setLocation("/Patient/1");
+ return output;
+ }
+
private String extractResponseAndClose(HttpResponse status) throws IOException {
if (status.getEntity() == null) {
return null;
@@ -207,7 +278,7 @@ public class AuthorizationInterceptorR4Test {
@Override
public List buildRuleList(RequestDetails theRequestDetails) {
return new RuleBuilder().allow("Rule 1").read().resourcesOfType(CarePlan.class).inCompartment("Patient", new IdType("Patient/845bd9f1-3635-4866-a6c8-1ca085df5c1a")).andThen().denyAll()
- .build();
+ .build();
}
});
@@ -264,108 +335,6 @@ public class AuthorizationInterceptorR4Test {
assertEquals(403, status.getStatusLine().getStatusCode());
}
-
- /**
- * See #762
- */
- //@Test
- public void testInstanceRuleOkForResourceWithNoId2() throws IOException {
-
- ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
- @Override
- public List buildRuleList(RequestDetails theRequestDetails) {
- return new RuleBuilder()
- .allow("transactions").transaction().withAnyOperation().andApplyNormalRules().andThen()
- .allow("write patient").write().resourcesOfType(Patient.class).withAnyId().andThen()
- .allow("write encounter").write().resourcesOfType(Encounter.class).withAnyId().andThen()
- .allow("write condition").write().resourcesOfType(Condition.class).withAnyId().andThen()
- .denyAll("deny all")
- .build();
- }
- });
-
-
-
- // Create a bundle that will be used as a transaction
- Bundle bundle = new Bundle();
- bundle.setType(Bundle.BundleType.TRANSACTION);
-
-
-
- String encounterId = "123-123";
- String encounterSystem = "http://our.internal.code.system/encounter";
- Encounter encounter = new Encounter();
-
- encounter.addIdentifier(new Identifier().setValue(encounterId)
- .setSystem(encounterSystem));
-
- encounter.setStatus(Encounter.EncounterStatus.FINISHED);
-
- Patient p = new Patient()
- .addIdentifier(new Identifier().setValue("321-321").setSystem("http://our.internal.code.system/patient"));
- p.setId(IdDt.newRandomUuid());
-
- // add patient to bundle so its created
- bundle.addEntry()
- .setFullUrl(p.getId())
- .setResource(p)
- .getRequest()
- .setUrl("Patient")
- .setMethod(Bundle.HTTPVerb.POST);
-
- Reference patientRef = new Reference(p.getId());
-
- encounter.setSubject(patientRef);
- Condition condition = new Condition()
- .setCode(new CodeableConcept().addCoding(
- new Coding("http://hl7.org/fhir/icd-10", "S53.40", "FOREARM SPRAIN / STRAIN")))
- .setSubject(patientRef);
-
- condition.setId(IdDt.newRandomUuid());
-
- // add condition to bundle so its created
- bundle.addEntry()
- .setFullUrl(condition.getId())
- .setResource(condition)
- .getRequest()
- .setUrl("Condition")
- .setMethod(Bundle.HTTPVerb.POST);
-
- Encounter.DiagnosisComponent dc = new Encounter.DiagnosisComponent();
-
- dc.setCondition(new Reference(condition.getId()));
- encounter.addDiagnosis(dc);
- CodeableConcept reason = new CodeableConcept();
- reason.setText("SLIPPED ON FLOOR,PAIN L) ELBOW");
- encounter.addReason(reason);
-
- // add encounter to bundle so its created
- bundle.addEntry()
- .setResource(encounter)
- .getRequest()
- .setUrl("Encounter")
- .setIfNoneExist("identifier=" + encounterSystem + "|" + encounterId)
- .setMethod(Bundle.HTTPVerb.POST);
-
- Bundle output = new Bundle();
- output.setType(Bundle.BundleType.TRANSACTIONRESPONSE);
- output.addEntry()
- .setResource(new Patient().setActive(true)) // don't give this an ID
- .getResponse().setLocation("/Patient/1");
-
-
- ourReturn = Collections.singletonList((Resource) output);
- HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/");
- httpPost.setEntity(createFhirResourceEntity(bundle));
- CloseableHttpResponse status = ourClient.execute(httpPost);
- String resp = extractResponseAndClose(status);
- assertEquals(200, status.getStatusLine().getStatusCode());
-
- ourLog.info(resp);
-
- }
-
-
@Test
public void testBatchWhenTransactionReadDenied() throws Exception {
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
@@ -561,7 +530,7 @@ public class AuthorizationInterceptorR4Test {
@Override
public List buildRuleList(RequestDetails theRequestDetails) {
return new RuleBuilder().deny("Rule 1").read().resourcesOfType(CarePlan.class).inCompartment("Patient", new IdType("Patient/845bd9f1-3635-4866-a6c8-1ca085df5c1a")).andThen().allowAll()
- .build();
+ .build();
}
});
@@ -623,6 +592,113 @@ public class AuthorizationInterceptorR4Test {
assertTrue(ourHitMethod);
}
+ /**
+ * See #762
+ */
+ @Test
+ public void testTransactionWithPlaceholderIdsResponseUnauthorized() throws IOException {
+
+ ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
+ @Override
+ public List buildRuleList(RequestDetails theRequestDetails) {
+ return new RuleBuilder()
+ .allow("transactions").transaction().withAnyOperation().andApplyNormalRules().andThen()
+ .allow("write patient").write().resourcesOfType(Patient.class).withAnyId().andThen()
+ .allow("write encounter").write().resourcesOfType(Encounter.class).withAnyId().andThen()
+ .allow("write condition").write().resourcesOfType(Condition.class).withAnyId().andThen()
+ .denyAll("deny all")
+ .build();
+ }
+ });
+
+ Bundle input = createTransactionWithPlaceholdersRequestBundle();
+ Bundle output = createTransactionWithPlaceholdersResponseBundle();
+
+ ourReturn = Collections.singletonList((Resource) output);
+ HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/");
+ httpPost.setEntity(createFhirResourceEntity(input));
+ CloseableHttpResponse status = ourClient.execute(httpPost);
+ String resp = extractResponseAndClose(status);
+ assertEquals(403, status.getStatusLine().getStatusCode());
+
+ ourLog.info(resp);
+
+ }
+
+ /**
+ * See #762
+ */
+ @Test
+ public void testTransactionWithPlaceholderIdsResponseAuthorized() throws IOException {
+
+ ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
+ @Override
+ public List buildRuleList(RequestDetails theRequestDetails) {
+ return new RuleBuilder()
+ .allow("transactions").transaction().withAnyOperation().andApplyNormalRules().andThen()
+ .allow("read patient").read().resourcesOfType(Patient.class).withAnyId().andThen()
+ .allow("write patient").write().resourcesOfType(Patient.class).withAnyId().andThen()
+ .allow("write encounter").write().resourcesOfType(Encounter.class).withAnyId().andThen()
+ .allow("write condition").write().resourcesOfType(Condition.class).withAnyId().andThen()
+ .denyAll("deny all")
+ .build();
+ }
+ });
+
+ Bundle input = createTransactionWithPlaceholdersRequestBundle();
+ Bundle output = createTransactionWithPlaceholdersResponseBundle();
+
+ ourReturn = Collections.singletonList((Resource) output);
+ HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/");
+ httpPost.setEntity(createFhirResourceEntity(input));
+ CloseableHttpResponse status = ourClient.execute(httpPost);
+ String resp = extractResponseAndClose(status);
+ assertEquals(200, status.getStatusLine().getStatusCode());
+
+ ourLog.info(resp);
+
+ }
+
+ @Test
+ public void testInvalidInstanceIds() throws Exception {
+ try {
+ new RuleBuilder().allow("Rule 1").write().instance((String) null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("theId must not be null or empty", e.getMessage());
+ }
+ try {
+ new RuleBuilder().allow("Rule 1").write().instance("");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("theId must not be null or empty", e.getMessage());
+ }
+ try {
+ new RuleBuilder().allow("Rule 1").write().instance("Observation/");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("theId must contain an ID part", e.getMessage());
+ }
+ try {
+ new RuleBuilder().allow("Rule 1").write().instance(new IdType());
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("theId.getValue() must not be null or empty", e.getMessage());
+ }
+ try {
+ new RuleBuilder().allow("Rule 1").write().instance(new IdType(""));
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("theId.getValue() must not be null or empty", e.getMessage());
+ }
+ try {
+ new RuleBuilder().allow("Rule 1").write().instance(new IdType("Observation", (String) null));
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("theId must contain an ID part", e.getMessage());
+ }
+ }
+
@Test
public void testMetadataAllow() throws Exception {
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
@@ -865,8 +941,8 @@ public class AuthorizationInterceptorR4Test {
@Override
public List buildRuleList(RequestDetails theRequestDetails) {
return new RuleBuilder()
- .allow("RULE 1").operation().named("opName").onAnyInstance().andThen()
- .build();
+ .allow("RULE 1").operation().named("opName").onAnyInstance().andThen()
+ .build();
}
});
@@ -1272,102 +1348,6 @@ public class AuthorizationInterceptorR4Test {
}
- @Test
- public void testReadPageRight() throws Exception {
- ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
- @Override
- public List buildRuleList(RequestDetails theRequestDetails) {
- return new RuleBuilder()
- .allow("Rule 1").read().resourcesOfType(Patient.class).inCompartment("Patient", new IdType("Patient/1"))
- .build();
- }
- });
-
- HttpGet httpGet;
- HttpResponse status;
- String respString;
- Bundle respBundle;
-
- ourReturn = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- ourReturn.add(createPatient(1));
- }
-
- ourHitMethod = false;
- httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_count=5&_format=json");
- status = ourClient.execute(httpGet);
- respString = extractResponseAndClose(status);
- assertEquals(200, status.getStatusLine().getStatusCode());
- assertTrue(ourHitMethod);
- respBundle = ourCtx.newJsonParser().parseResource(Bundle.class, respString);
- assertEquals(5, respBundle.getEntry().size());
- assertEquals(10, respBundle.getTotal());
- assertEquals("Patient/1", respBundle.getEntry().get(0).getResource().getIdElement().toUnqualifiedVersionless().getValue());
- assertNotNull(respBundle.getLink("next"));
-
- // Load next page
-
- ourHitMethod = false;
- httpGet = new HttpGet(respBundle.getLink("next").getUrl());
- status = ourClient.execute(httpGet);
- respString = extractResponseAndClose(status);
- assertEquals(200, status.getStatusLine().getStatusCode());
- assertFalse(ourHitMethod);
- respBundle = ourCtx.newJsonParser().parseResource(Bundle.class, respString);
- assertEquals(5, respBundle.getEntry().size());
- assertEquals(10, respBundle.getTotal());
- assertEquals("Patient/1", respBundle.getEntry().get(0).getResource().getIdElement().toUnqualifiedVersionless().getValue());
- assertNull(respBundle.getLink("next"));
-
- }
-
- @Test
- public void testReadPageWrong() throws Exception {
- ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
- @Override
- public List buildRuleList(RequestDetails theRequestDetails) {
- return new RuleBuilder()
- .allow("Rule 1").read().resourcesOfType(Patient.class).inCompartment("Patient", new IdType("Patient/1"))
- .build();
- }
- });
-
- HttpGet httpGet;
- HttpResponse status;
- String respString;
- Bundle respBundle;
-
- ourReturn = new ArrayList<>();
- for (int i = 0; i < 5; i++) {
- ourReturn.add(createPatient(1));
- }
- for (int i = 0; i < 5; i++) {
- ourReturn.add(createPatient(2));
- }
-
- ourHitMethod = false;
- httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_count=5&_format=json");
- status = ourClient.execute(httpGet);
- respString = extractResponseAndClose(status);
- assertEquals(200, status.getStatusLine().getStatusCode());
- assertTrue(ourHitMethod);
- respBundle = ourCtx.newJsonParser().parseResource(Bundle.class, respString);
- assertEquals(5, respBundle.getEntry().size());
- assertEquals(10, respBundle.getTotal());
- assertEquals("Patient/1", respBundle.getEntry().get(0).getResource().getIdElement().toUnqualifiedVersionless().getValue());
- assertNotNull(respBundle.getLink("next"));
-
- // Load next page
-
- ourHitMethod = false;
- httpGet = new HttpGet(respBundle.getLink("next").getUrl());
- status = ourClient.execute(httpGet);
- respString = extractResponseAndClose(status);
- assertEquals(403, status.getStatusLine().getStatusCode());
- assertFalse(ourHitMethod);
-
- }
-
@Test
public void testReadByCompartmentWrong() throws Exception {
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
@@ -1436,6 +1416,147 @@ public class AuthorizationInterceptorR4Test {
}
+ @Test
+ public void testReadByInstance() throws Exception {
+ ourConditionalCreateId = "1";
+
+ ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
+ @Override
+ public List buildRuleList(RequestDetails theRequestDetails) {
+ return new RuleBuilder()
+ .allow("Rule 1").read().instance("Observation/900").andThen()
+ .allow("Rule 1").read().instance("901").andThen()
+ .build();
+ }
+ });
+
+ HttpResponse status;
+ String response;
+ HttpGet httpGet;
+
+ ourReturn = Collections.singletonList(createObservation(900, "Patient/1"));
+ ourHitMethod = false;
+ httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation/900");
+ status = ourClient.execute(httpGet);
+ response = extractResponseAndClose(status);
+ assertEquals(200, status.getStatusLine().getStatusCode());
+ assertTrue(ourHitMethod);
+
+ ourReturn = Collections.singletonList(createPatient(901));
+ ourHitMethod = false;
+ httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/901");
+ status = ourClient.execute(httpGet);
+ response = extractResponseAndClose(status);
+ assertEquals(200, status.getStatusLine().getStatusCode());
+ assertTrue(ourHitMethod);
+
+ ourReturn = Collections.singletonList(createPatient(1));
+ ourHitMethod = false;
+ httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=json");
+ status = ourClient.execute(httpGet);
+ response = extractResponseAndClose(status);
+ assertEquals(403, status.getStatusLine().getStatusCode());
+ assertEquals(ERR403, response);
+ assertFalse(ourHitMethod);
+
+ }
+
+ @Test
+ public void testReadPageRight() throws Exception {
+ ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
+ @Override
+ public List buildRuleList(RequestDetails theRequestDetails) {
+ return new RuleBuilder()
+ .allow("Rule 1").read().resourcesOfType(Patient.class).inCompartment("Patient", new IdType("Patient/1"))
+ .build();
+ }
+ });
+
+ HttpGet httpGet;
+ HttpResponse status;
+ String respString;
+ Bundle respBundle;
+
+ ourReturn = new ArrayList<>();
+ for (int i = 0; i < 10; i++) {
+ ourReturn.add(createPatient(1));
+ }
+
+ ourHitMethod = false;
+ httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_count=5&_format=json");
+ status = ourClient.execute(httpGet);
+ respString = extractResponseAndClose(status);
+ assertEquals(200, status.getStatusLine().getStatusCode());
+ assertTrue(ourHitMethod);
+ respBundle = ourCtx.newJsonParser().parseResource(Bundle.class, respString);
+ assertEquals(5, respBundle.getEntry().size());
+ assertEquals(10, respBundle.getTotal());
+ assertEquals("Patient/1", respBundle.getEntry().get(0).getResource().getIdElement().toUnqualifiedVersionless().getValue());
+ assertNotNull(respBundle.getLink("next"));
+
+ // Load next page
+
+ ourHitMethod = false;
+ httpGet = new HttpGet(respBundle.getLink("next").getUrl());
+ status = ourClient.execute(httpGet);
+ respString = extractResponseAndClose(status);
+ assertEquals(200, status.getStatusLine().getStatusCode());
+ assertFalse(ourHitMethod);
+ respBundle = ourCtx.newJsonParser().parseResource(Bundle.class, respString);
+ assertEquals(5, respBundle.getEntry().size());
+ assertEquals(10, respBundle.getTotal());
+ assertEquals("Patient/1", respBundle.getEntry().get(0).getResource().getIdElement().toUnqualifiedVersionless().getValue());
+ assertNull(respBundle.getLink("next"));
+
+ }
+
+ @Test
+ public void testReadPageWrong() throws Exception {
+ ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
+ @Override
+ public List buildRuleList(RequestDetails theRequestDetails) {
+ return new RuleBuilder()
+ .allow("Rule 1").read().resourcesOfType(Patient.class).inCompartment("Patient", new IdType("Patient/1"))
+ .build();
+ }
+ });
+
+ HttpGet httpGet;
+ HttpResponse status;
+ String respString;
+ Bundle respBundle;
+
+ ourReturn = new ArrayList<>();
+ for (int i = 0; i < 5; i++) {
+ ourReturn.add(createPatient(1));
+ }
+ for (int i = 0; i < 5; i++) {
+ ourReturn.add(createPatient(2));
+ }
+
+ ourHitMethod = false;
+ httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_count=5&_format=json");
+ status = ourClient.execute(httpGet);
+ respString = extractResponseAndClose(status);
+ assertEquals(200, status.getStatusLine().getStatusCode());
+ assertTrue(ourHitMethod);
+ respBundle = ourCtx.newJsonParser().parseResource(Bundle.class, respString);
+ assertEquals(5, respBundle.getEntry().size());
+ assertEquals(10, respBundle.getTotal());
+ assertEquals("Patient/1", respBundle.getEntry().get(0).getResource().getIdElement().toUnqualifiedVersionless().getValue());
+ assertNotNull(respBundle.getLink("next"));
+
+ // Load next page
+
+ ourHitMethod = false;
+ httpGet = new HttpGet(respBundle.getLink("next").getUrl());
+ status = ourClient.execute(httpGet);
+ respString = extractResponseAndClose(status);
+ assertEquals(403, status.getStatusLine().getStatusCode());
+ assertFalse(ourHitMethod);
+
+ }
+
@Test
public void testTransactionWriteGood() throws Exception {
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
@@ -1818,82 +1939,6 @@ public class AuthorizationInterceptorR4Test {
}
- @Test
- public void testInvalidInstanceIds() throws Exception {
- try {
- new RuleBuilder().allow("Rule 1").write().instance((String) null);
- fail();
- } catch (NullPointerException e) {
- assertEquals("theId must not be null or empty", e.getMessage());
- }
- try {
- new RuleBuilder().allow("Rule 1").write().instance("");
- fail();
- } catch (IllegalArgumentException e) {
- assertEquals("theId must not be null or empty", e.getMessage());
- }
- try {
- new RuleBuilder().allow("Rule 1").write().instance("Observation/");
- fail();
- } catch (IllegalArgumentException e) {
- assertEquals("theId must contain an ID part", e.getMessage());
- }
- try {
- new RuleBuilder().allow("Rule 1").write().instance(new IdType());
- fail();
- } catch (NullPointerException e) {
- assertEquals("theId.getValue() must not be null or empty", e.getMessage());
- }
- try {
- new RuleBuilder().allow("Rule 1").write().instance(new IdType(""));
- fail();
- } catch (NullPointerException e) {
- assertEquals("theId.getValue() must not be null or empty", e.getMessage());
- }
- try {
- new RuleBuilder().allow("Rule 1").write().instance(new IdType("Observation", (String) null));
- fail();
- } catch (NullPointerException e) {
- assertEquals("theId must contain an ID part", e.getMessage());
- }
- }
-
- @Test
- public void testWritePatchByInstance() throws Exception {
- ourConditionalCreateId = "1";
-
- ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
- @Override
- public List buildRuleList(RequestDetails theRequestDetails) {
- return new RuleBuilder()
- .allow("Rule 1").write().instance("Patient/900").andThen()
- .build();
- }
- });
-
- HttpEntityEnclosingRequestBase httpPost;
- HttpResponse status;
- String response;
-
- String input = "[ { \"op\": \"replace\", \"path\": \"/gender\", \"value\": \"male\" } ]";
-
- ourHitMethod = false;
- httpPost = new HttpPatch("http://localhost:" + ourPort + "/Patient/900");
- httpPost.setEntity(new StringEntity(input, ContentType.parse("application/json-patch+json")));
- status = ourClient.execute(httpPost);
- response = extractResponseAndClose(status);
- assertEquals(204, status.getStatusLine().getStatusCode());
- assertTrue(ourHitMethod);
-
- ourHitMethod = false;
- httpPost = new HttpPatch("http://localhost:" + ourPort + "/Patient/999");
- httpPost.setEntity(new StringEntity(input, ContentType.parse("application/json-patch+json")));
- status = ourClient.execute(httpPost);
- response = extractResponseAndClose(status);
- assertEquals(403, status.getStatusLine().getStatusCode());
- assertFalse(ourHitMethod);
- }
-
@Test
public void testWriteByInstance() throws Exception {
ourConditionalCreateId = "1";
@@ -1949,48 +1994,39 @@ public class AuthorizationInterceptorR4Test {
}
@Test
- public void testReadByInstance() throws Exception {
+ public void testWritePatchByInstance() throws Exception {
ourConditionalCreateId = "1";
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
@Override
public List buildRuleList(RequestDetails theRequestDetails) {
return new RuleBuilder()
- .allow("Rule 1").read().instance("Observation/900").andThen()
- .allow("Rule 1").read().instance("901").andThen()
+ .allow("Rule 1").write().instance("Patient/900").andThen()
.build();
}
});
+ HttpEntityEnclosingRequestBase httpPost;
HttpResponse status;
String response;
- HttpGet httpGet;
- ourReturn = Collections.singletonList(createObservation(900, "Patient/1"));
+ String input = "[ { \"op\": \"replace\", \"path\": \"/gender\", \"value\": \"male\" } ]";
+
ourHitMethod = false;
- httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation/900");
- status = ourClient.execute(httpGet);
+ httpPost = new HttpPatch("http://localhost:" + ourPort + "/Patient/900");
+ httpPost.setEntity(new StringEntity(input, ContentType.parse("application/json-patch+json")));
+ status = ourClient.execute(httpPost);
response = extractResponseAndClose(status);
- assertEquals(200, status.getStatusLine().getStatusCode());
+ assertEquals(204, status.getStatusLine().getStatusCode());
assertTrue(ourHitMethod);
- ourReturn = Collections.singletonList(createPatient(901));
ourHitMethod = false;
- httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/901");
- status = ourClient.execute(httpGet);
- response = extractResponseAndClose(status);
- assertEquals(200, status.getStatusLine().getStatusCode());
- assertTrue(ourHitMethod);
-
- ourReturn = Collections.singletonList(createPatient(1));
- ourHitMethod = false;
- httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=json");
- status = ourClient.execute(httpGet);
+ httpPost = new HttpPatch("http://localhost:" + ourPort + "/Patient/999");
+ httpPost.setEntity(new StringEntity(input, ContentType.parse("application/json-patch+json")));
+ status = ourClient.execute(httpPost);
response = extractResponseAndClose(status);
assertEquals(403, status.getStatusLine().getStatusCode());
- assertEquals(ERR403, response);
assertFalse(ourHitMethod);
-
}
@AfterClass
@@ -2220,6 +2256,14 @@ public class AuthorizationInterceptorR4Test {
return (Parameters) new Parameters().setId("1");
}
+ @Patch()
+ public MethodOutcome patch(@IdParam IdType theId, @ResourceParam String theResource, PatchTypeEnum thePatchType) {
+ ourHitMethod = true;
+
+ MethodOutcome retVal = new MethodOutcome();
+ return retVal;
+ }
+
@Read(version = true)
public Patient read(@IdParam IdType theId) {
ourHitMethod = true;
@@ -2252,17 +2296,9 @@ public class AuthorizationInterceptorR4Test {
return retVal;
}
- @Patch()
- public MethodOutcome patch(@IdParam IdType theId, @ResourceParam String theResource, PatchTypeEnum thePatchType) {
- ourHitMethod = true;
-
- MethodOutcome retVal = new MethodOutcome();
- return retVal;
- }
-
@Validate
public MethodOutcome validate(@ResourceParam Patient theResource, @IdParam IdType theId, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding,
- @Validate.Mode ValidationModeEnum theMode, @Validate.Profile String theProfile, RequestDetails theRequestDetails) {
+ @Validate.Mode ValidationModeEnum theMode, @Validate.Profile String theProfile, RequestDetails theRequestDetails) {
ourHitMethod = true;
OperationOutcome oo = new OperationOutcome();
oo.addIssue().setDiagnostics("OK");
@@ -2271,7 +2307,7 @@ public class AuthorizationInterceptorR4Test {
@Validate
public MethodOutcome validate(@ResourceParam Patient theResource, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
- @Validate.Profile String theProfile, RequestDetails theRequestDetails) {
+ @Validate.Profile String theProfile, RequestDetails theRequestDetails) {
ourHitMethod = true;
OperationOutcome oo = new OperationOutcome();
oo.addIssue().setDiagnostics("OK");