Authorize batch operation in AuthorizationInterceptor

This commit is contained in:
James Agnew 2018-10-19 09:45:56 -04:00
parent c8db7fe035
commit aa177c1421
5 changed files with 66 additions and 17 deletions

View File

@ -525,14 +525,6 @@ public class RuleBuilder implements IAuthRuleBuilder {
rule.setOp(RuleOpEnum.TRANSACTION);
rule.setTransactionAppliesToOp(TransactionAppliesToEnum.ANY_OPERATION);
myRules.add(rule);
// Allow batch
rule = new RuleImplOp(myRuleName);
rule.setMode(myRuleMode);
rule.setOp(RuleOpEnum.BATCH);
rule.setTransactionAppliesToOp(TransactionAppliesToEnum.ANY_OPERATION);
myRules.add(rule);
return new RuleBuilderFinished(rule);
}

View File

@ -174,7 +174,6 @@ class RuleImplOp extends BaseRule /* implements IAuthRule */ {
return null;
}
break;
case BATCH:
case TRANSACTION:
if (!(theOperation == RestOperationTypeEnum.TRANSACTION)) {
return null;
@ -185,12 +184,16 @@ class RuleImplOp extends BaseRule /* implements IAuthRule */ {
}
List<BundleEntryParts> inputResources = BundleUtil.toListOfEntries(ctx, (IBaseBundle) theInputResource);
Verdict verdict = null;
boolean allComponentsAreGets = true;
for (BundleEntryParts nextPart : inputResources) {
IBaseResource inputResource = nextPart.getResource();
RestOperationTypeEnum operation = null;
if (nextPart.getRequestType() == RequestTypeEnum.GET) {
continue;
} else {
allComponentsAreGets = false;
}
if (nextPart.getRequestType() == RequestTypeEnum.POST) {
operation = RestOperationTypeEnum.CREATE;
@ -219,6 +222,15 @@ class RuleImplOp extends BaseRule /* implements IAuthRule */ {
verdict = newVerdict;
}
}
/*
* If we're handling a transaction with all gets and nothing else, we'll
* be applying security on the way out
*/
if (allComponentsAreGets) {
return newVerdict();
}
return verdict;
} else if (theOutputResource != null) {
@ -453,9 +465,8 @@ class RuleImplOp extends BaseRule /* implements IAuthRule */ {
//noinspection EnumSwitchStatementWhichMissesCases
switch (theOp) {
case TRANSACTION:
return "transaction".equals(bundleType);
case BATCH:
return "batch".equals(bundleType);
return "transaction".equals(bundleType)
|| "batch".equals(bundleType);
default:
return false;
}

View File

@ -25,9 +25,11 @@ enum RuleOpEnum {
WRITE,
ALLOW_ALL,
DENY_ALL,
/**
* Transaction applies to both transaction and batch
*/
TRANSACTION,
METADATA,
BATCH,
DELETE,
OPERATION,
PATCH

View File

@ -499,6 +499,45 @@ public class AuthorizationInterceptorR4Test {
status = ourClient.execute(httpPost);
extractResponseAndClose(status);
assertEquals(200, status.getStatusLine().getStatusCode());
}
@Test
public void testBatchAllowedWithGets() throws Exception {
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
@Override
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
return new RuleBuilder()
.allow("Rule 1").transaction().withAnyOperation().andApplyNormalRules().andThen()
.allow("Rule 2").write().allResources().inCompartment("Patient", new IdType("Patient/1")).andThen()
.allow("Rule 2").read().allResources().inCompartment("Patient", new IdType("Patient/1")).andThen()
.build();
}
});
HttpPost httpPost;
HttpResponse status;
// Bundle with GETs
Bundle input = new Bundle();
input.setType(Bundle.BundleType.BATCH);
input.addEntry().getRequest().setUrl("Patient?").setMethod(Bundle.HTTPVerb.GET);
Bundle output = new Bundle();
output.setType(Bundle.BundleType.TRANSACTIONRESPONSE);
output.addEntry().getResponse().setLocation("/Patient/1");
ourReturn = Collections.singletonList(output);
ourHitMethod = false;
httpPost = new HttpPost("http://localhost:" + ourPort + "/");
httpPost.setEntity(createFhirResourceEntity(input));
status = ourClient.execute(httpPost);
extractResponseAndClose(status);
assertEquals(200, status.getStatusLine().getStatusCode());
}
@Test

View File

@ -100,6 +100,11 @@
permission is granted. This has been corrected so that transaction() allows both
batch and transaction requests to proceed.
</action>
<action type="fix">
The AuthorizationInterceptor was previously not able to authorize the FHIR
batch operation. As of this version, when authorizing a transaction operation
(via the transaction() rule), both batch and transaction will be allowed.
</action>
</release>
<release version="3.5.0" date="2018-09-17">