Allow history operation at type level with authorizationinterceptor

This commit is contained in:
James Agnew 2017-01-16 18:41:39 -06:00
parent 55a1d69e73
commit 22f796fa7c
4 changed files with 100 additions and 23 deletions

View File

@ -24,6 +24,8 @@ import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
@ -75,6 +77,7 @@ class RuleImplOp extends BaseRule implements IAuthRule {
case SEARCH_TYPE:
case HISTORY_INSTANCE:
case HISTORY_SYSTEM:
case HISTORY_TYPE:
return new Verdict(PolicyEnum.ALLOW, this);
default:
return null;
@ -254,6 +257,19 @@ class RuleImplOp extends BaseRule implements IAuthRule {
return newVerdict();
}
@Override
public String toString() {
ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
builder.append("op", myOp);
builder.append("transactionAppliesToOp", myTransactionAppliesToOp);
builder.append("appliesTo", myAppliesTo);
builder.append("appliesToTypes", myAppliesToTypes);
builder.append("classifierCompartmentName", myClassifierCompartmentName);
builder.append("classifierCompartmentOwners", myClassifierCompartmentOwners);
builder.append("classifierType", myClassifierType);
return builder.toString();
}
private boolean requestAppliesToTransaction(FhirContext theContext, RuleOpEnum theOp, IBaseResource theInputResource) {
if (!"Bundle".equals(theContext.getResourceDefinition(theInputResource).getName())) {
return false;

View File

@ -0,0 +1,11 @@
package ca.uhn.fhir.rest.server.interceptor.auth;
import org.junit.Test;
public class RuleImplOpTest {
@Test
public void testToString() {
new RuleImplOp("").toString();
}
}

View File

@ -17,12 +17,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
@ -44,28 +39,13 @@ import ca.uhn.fhir.model.dstu2.resource.*;
import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
import ca.uhn.fhir.model.primitive.IdDt;
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.Read;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.method.IRequestOperationCallback;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.AddProfileTagEnum;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.PortUtil;
@ -119,6 +99,12 @@ public class AuthorizationInterceptorDstu2Test {
return retVal;
}
private IResource createPatient(Integer theId, int theVersion) {
IResource retVal = createPatient(theId);
retVal.setId(retVal.getId().withVersion(Integer.toString(theVersion)));
return retVal;
}
private IResource createPatient(Integer theId) {
Patient retVal = new Patient();
if (theId != null) {
@ -939,6 +925,46 @@ public class AuthorizationInterceptorDstu2Test {
assertFalse(ourHitMethod);
}
@Test
public void testHistoryWithReadAll() throws Exception {
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
@Override
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
//@formatter:off
return new RuleBuilder()
.allow("Rule 1").read().allResources().withAnyId()
.build();
//@formatter:on
}
});
HttpGet httpGet;
HttpResponse status;
ourReturn = Arrays.asList(createPatient(2, 1));
ourHitMethod = false;
httpGet = new HttpGet("http://localhost:" + ourPort + "/_history");
status = ourClient.execute(httpGet);
extractResponseAndClose(status);
assertEquals(200, status.getStatusLine().getStatusCode());
assertTrue(ourHitMethod);
ourHitMethod = false;
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/_history");
status = ourClient.execute(httpGet);
extractResponseAndClose(status);
assertEquals(200, status.getStatusLine().getStatusCode());
assertTrue(ourHitMethod);
ourHitMethod = false;
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/_history");
status = ourClient.execute(httpGet);
extractResponseAndClose(status);
assertEquals(200, status.getStatusLine().getStatusCode());
assertTrue(ourHitMethod);
}
@Test
public void testReadByAnyId() throws Exception {
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
@ -1685,6 +1711,19 @@ public class AuthorizationInterceptorDstu2Test {
return retVal;
}
@History()
public List<IResource> history() {
ourHitMethod = true;
return (ourReturn);
}
@History()
public List<IResource> history(@IdParam IdDt theId) {
ourHitMethod = true;
return (ourReturn);
}
@Delete()
public MethodOutcome delete(IRequestOperationCallback theRequestOperationCallback, @IdParam IdDt theId, @ConditionalUrlParam String theConditionalUrl, RequestDetails theRequestDetails) {
ourHitMethod = true;
@ -1794,6 +1833,13 @@ public class AuthorizationInterceptorDstu2Test {
return (Bundle) ourReturn.get(0);
}
@History()
public List<IResource> history() {
ourHitMethod = true;
return (ourReturn);
}
}
}

View File

@ -209,6 +209,10 @@
sources and JavaDoc JARs. Thanks to Keith Boone for pointing
this out!
</action>
<action type="fix">
Server AuthorizationInterceptor always rejects history operation
at the type level even if rules should allow it.
</action>
</release>
<release version="2.1" date="2016-11-11">
<action type="add">