Merge pull request #806 from honestica/quickfix-imcompartment

fix inCompartment for a collection of owners
This commit is contained in:
James Agnew 2018-03-19 06:16:12 -04:00 committed by GitHub
commit e9ee87210a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 121 additions and 0 deletions

View File

@ -20,6 +20,7 @@ import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Observation; import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus; import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.dstu3.model.Patient; import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.Practitioner;
import org.hl7.fhir.dstu3.model.Reference; import org.hl7.fhir.dstu3.model.Reference;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass; import org.junit.AfterClass;
@ -27,6 +28,7 @@ import org.junit.Test;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.startsWith;
@ -41,6 +43,64 @@ public class AuthorizationInterceptorResourceProviderDstu3Test extends BaseResou
unregisterInterceptors(); unregisterInterceptors();
} }
/**
* See #778
*/
@Test
public void testReadingObservationAccessRight() throws IOException {
Practitioner practitioner1 = new Practitioner();
final IIdType practitionerId1 = ourClient.create().resource(practitioner1).execute().getId().toUnqualifiedVersionless();
Practitioner practitioner2 = new Practitioner();
final IIdType practitionerId2 = ourClient.create().resource(practitioner2).execute().getId().toUnqualifiedVersionless();
Patient patient = new Patient();
patient.setActive(true);
final IIdType patientId = ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
ourRestServer.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
@Override
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
// allow write all Observation resource
// allow read only Observation resource in which it has a practitioner1 or practitioner2 compartment
return new RuleBuilder().allow()
.write()
.resourcesOfType(Observation.class)
.withAnyId()
.andThen()
.allow()
.read()
.resourcesOfType(Observation.class)
.inCompartment("Practitioner", Arrays.asList(practitionerId1, practitionerId2))
.andThen()
.denyAll()
.build();
}
});
Observation obs1 = new Observation();
obs1.setStatus(ObservationStatus.FINAL);
obs1.setPerformer(
Arrays.asList(new Reference(practitionerId1), new Reference(practitionerId2)));
IIdType oid1 = ourClient.create().resource(obs1).execute().getId().toUnqualified();
// Observation with practitioner1 and practitioner1 as the Performer -> should have the read access
ourClient.read().resource(Observation.class).withId(oid1).execute();
Observation obs2 = new Observation();
obs2.setStatus(ObservationStatus.FINAL);
obs2.setSubject(new Reference(patientId));
IIdType oid2 = ourClient.create().resource(obs2).execute().getId().toUnqualified();
// Observation with patient as the subject -> read access should be blocked
try {
ourClient.read().resource(Observation.class).withId(oid2).execute();
fail();
} catch (ForbiddenOperationException e) {
// good
}
}
/** /**
* See #667 * See #667
*/ */

View File

@ -25,6 +25,7 @@ import org.junit.Test;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.startsWith;
@ -39,6 +40,64 @@ public class AuthorizationInterceptorResourceProviderR4Test extends BaseResource
unregisterInterceptors(); unregisterInterceptors();
} }
/**
* See #778
*/
@Test
public void testReadingObservationAccessRight() throws IOException {
Practitioner practitioner1 = new Practitioner();
final IIdType practitionerId1 = myClient.create().resource(practitioner1).execute().getId().toUnqualifiedVersionless();
Practitioner practitioner2 = new Practitioner();
final IIdType practitionerId2 = myClient.create().resource(practitioner2).execute().getId().toUnqualifiedVersionless();
Patient patient = new Patient();
patient.setActive(true);
final IIdType patientId = myClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
ourRestServer.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
@Override
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
// allow write all Observation resource
// allow read only Observation resource in which it has a practitioner1 or practitioner2 compartment
return new RuleBuilder().allow()
.write()
.resourcesOfType(Observation.class)
.withAnyId()
.andThen()
.allow()
.read()
.resourcesOfType(Observation.class)
.inCompartment("Practitioner", Arrays.asList(practitionerId1, practitionerId2))
.andThen()
.denyAll()
.build();
}
});
Observation obs1 = new Observation();
obs1.setStatus(ObservationStatus.FINAL);
obs1.setPerformer(
Arrays.asList(new Reference(practitionerId1), new Reference(practitionerId2)));
IIdType oid1 = myClient.create().resource(obs1).execute().getId().toUnqualified();
// Observation with practitioner1 and practitioner1 as the Performer -> should have the read access
myClient.read().resource(Observation.class).withId(oid1).execute();
Observation obs2 = new Observation();
obs2.setStatus(ObservationStatus.FINAL);
obs2.setSubject(new Reference(patientId));
IIdType oid2 = myClient.create().resource(obs2).execute().getId().toUnqualified();
// Observation with patient as the subject -> read access should be blocked
try {
myClient.read().resource(Observation.class).withId(oid2).execute();
fail();
} catch (ForbiddenOperationException e) {
// good
}
}
/** /**
* See #667 * See #667
*/ */

View File

@ -362,6 +362,8 @@ public class RuleBuilder implements IAuthRuleBuilder {
for (IIdType next : theOwners) { for (IIdType next : theOwners) {
validateOwner(next); validateOwner(next);
} }
myInCompartmentName = theCompartmentName;
myInCompartmentOwners = theOwners;
myClassifierType = ClassifierTypeEnum.IN_COMPARTMENT; myClassifierType = ClassifierTypeEnum.IN_COMPARTMENT;
return finished(); return finished();
} }