updated IResourceAuditor interface
This commit is contained in:
parent
025db56fe9
commit
5f3a366ab0
|
@ -38,20 +38,24 @@ public class UserInfoInterceptor implements IClientInterceptor {
|
||||||
|
|
||||||
public static final String HEADER_USER_ID = "fhir-user-id";
|
public static final String HEADER_USER_ID = "fhir-user-id";
|
||||||
public static final String HEADER_USER_NAME = "fhir-user-name";
|
public static final String HEADER_USER_NAME = "fhir-user-name";
|
||||||
|
public static final String HEADER_APPLICATION_NAME = "fhir-app-name";
|
||||||
|
|
||||||
private String myUserId;
|
private String myUserId;
|
||||||
private String myUserName;
|
private String myUserName;
|
||||||
|
private String myAppName;
|
||||||
|
|
||||||
public UserInfoInterceptor(String theUserId, String theUserName) {
|
public UserInfoInterceptor(String theUserId, String theUserName, String theAppName) {
|
||||||
super();
|
super();
|
||||||
myUserId = theUserId;
|
myUserId = theUserId;
|
||||||
myUserName = theUserName;
|
myUserName = theUserName;
|
||||||
|
myAppName = theAppName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void interceptRequest(HttpRequestBase theRequest) {
|
public void interceptRequest(HttpRequestBase theRequest) {
|
||||||
if(myUserId != null) theRequest.addHeader(HEADER_USER_ID, myUserId);
|
if(myUserId != null) theRequest.addHeader(HEADER_USER_ID, myUserId);
|
||||||
if(myUserName != null) theRequest.addHeader(HEADER_USER_NAME, myUserName);
|
if(myUserName != null) theRequest.addHeader(HEADER_USER_NAME, myUserName);
|
||||||
|
if(myAppName != null) theRequest.addHeader(HEADER_APPLICATION_NAME, myAppName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,7 +20,7 @@ package ca.uhn.fhir.rest.server.audit;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
|
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
|
||||||
|
@ -29,17 +29,53 @@ import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
||||||
|
|
||||||
|
|
||||||
public interface IResourceAuditor<T extends IResource> {
|
public interface IResourceAuditor<T extends IResource> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the resource to be audited
|
||||||
|
*/
|
||||||
public T getResource();
|
public T getResource();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param resource the resource to be audited by this auditor
|
||||||
|
*/
|
||||||
public void setResource(T resource);
|
public void setResource(T resource);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this resource is to be audited, false otherwise
|
||||||
|
*/
|
||||||
public boolean isAuditable();
|
public boolean isAuditable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An instance-specific descriptor of the Participant Object ID audited, such as a person's name
|
||||||
|
* @return the descriptive name of the resource object
|
||||||
|
*/
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the identifier of the resource to be audited
|
||||||
|
*/
|
||||||
public BaseIdentifierDt getIdentifier();
|
public BaseIdentifierDt getIdentifier();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the SecurityEventObjectTypeEnum of this resource
|
||||||
|
*/
|
||||||
public SecurityEventObjectTypeEnum getType();
|
public SecurityEventObjectTypeEnum getType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a text description of the resource
|
||||||
|
*/
|
||||||
public String getDescription();
|
public String getDescription();
|
||||||
//public List<ObjectDetail> getDetail(); //see operationoutcome -- need to move specifics insto dstu and keep base objects in core
|
|
||||||
|
/**
|
||||||
|
* @return a map of additional details to be audited
|
||||||
|
*/
|
||||||
|
public Map<String, String> getDetail();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Denotes policy-defined sensitivity for the Participant Object ID such as VIP, HIV status, mental health status or similar topics
|
||||||
|
* @return the sensitivity of this resource
|
||||||
|
*/
|
||||||
public SecurityEventObjectSensitivityEnum getSensitivity();
|
public SecurityEventObjectSensitivityEnum getSensitivity();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,11 @@ package ca.uhn.fhir.rest.server.audit;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ObjectDetail;
|
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectSensitivityEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectSensitivityEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
||||||
|
|
||||||
|
@ -41,7 +40,7 @@ public class DiagnosticReportAuditor implements IResourceAuditor<DiagnosticRepor
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
if(myDiagnosticReport != null){
|
if(myDiagnosticReport != null){
|
||||||
return myDiagnosticReport.getName().getText().getValue();
|
return "Diagnostic Report: " + myDiagnosticReport.getName().getText().getValue();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -75,25 +74,15 @@ public class DiagnosticReportAuditor implements IResourceAuditor<DiagnosticRepor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ObjectDetail> getDetail() {
|
public Map<String, String> getDetail() {
|
||||||
List<ObjectDetail> details = new ArrayList<ObjectDetail>();
|
Map<String, String> details = new HashMap<String, String>();
|
||||||
details.add(makeObjectDetail("dateIssued", myDiagnosticReport.getIssued().getValueAsString()));
|
details.put("dateIssued", myDiagnosticReport.getIssued().getValueAsString());
|
||||||
details.add(makeObjectDetail("version", myDiagnosticReport.getId().getVersionIdPart()));
|
details.put("version", myDiagnosticReport.getId().getVersionIdPart());
|
||||||
return details;
|
return details;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SecurityEventObjectSensitivityEnum getSensitivity() {
|
public SecurityEventObjectSensitivityEnum getSensitivity() {
|
||||||
return null; //no sensitivity indicated
|
return null; //no sensitivity indicated
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectDetail makeObjectDetail(String type, String value) {
|
|
||||||
ObjectDetail detail = new ObjectDetail();
|
|
||||||
if(type != null)
|
|
||||||
detail.setType(type);
|
|
||||||
if(value != null)
|
|
||||||
detail.setValue(value.getBytes());
|
|
||||||
return detail;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,11 @@ package ca.uhn.fhir.rest.server.audit;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Encounter;
|
import ca.uhn.fhir.model.dstu.resource.Encounter;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ObjectDetail;
|
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectSensitivityEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectSensitivityEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
||||||
|
|
||||||
|
@ -54,7 +53,7 @@ public class EncounterAuditor implements IResourceAuditor<Encounter> {
|
||||||
String id = myEncounter.getIdentifierFirstRep().getValue().getValue();
|
String id = myEncounter.getIdentifierFirstRep().getValue().getValue();
|
||||||
String system = myEncounter.getIdentifierFirstRep().getSystem().getValueAsString();
|
String system = myEncounter.getIdentifierFirstRep().getSystem().getValueAsString();
|
||||||
String service = myEncounter.getServiceProvider().getDisplay().getValue();
|
String service = myEncounter.getServiceProvider().getDisplay().getValue();
|
||||||
return id + "/" + system + ": " + service;
|
return "Encounter: " + id + "/" + system + ": " + service;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -79,31 +78,22 @@ public class EncounterAuditor implements IResourceAuditor<Encounter> {
|
||||||
String status = myEncounter.getStatus().getValueAsString();
|
String status = myEncounter.getStatus().getValueAsString();
|
||||||
String startDate = myEncounter.getPeriod().getStart().getValueAsString();
|
String startDate = myEncounter.getPeriod().getStart().getValueAsString();
|
||||||
String endDate = myEncounter.getPeriod().getEnd().getValueAsString();
|
String endDate = myEncounter.getPeriod().getEnd().getValueAsString();
|
||||||
return type + ": " + status +", "+ startDate + " - " + endDate;
|
return "Encounter: " + type + ": " + status +", "+ startDate + " - " + endDate;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ObjectDetail> getDetail() {
|
public Map<String, String> getDetail() {
|
||||||
List<ObjectDetail> details = new ArrayList<ObjectDetail>();
|
Map<String, String> details = new HashMap<String, String>();
|
||||||
details.add(makeObjectDetail("startDate", myEncounter.getPeriod().getStart().getValueAsString()));
|
details.put("startDate", myEncounter.getPeriod().getStart().getValueAsString());
|
||||||
details.add(makeObjectDetail("endDate", myEncounter.getPeriod().getEnd().getValueAsString()));
|
details.put("endDate", myEncounter.getPeriod().getEnd().getValueAsString());
|
||||||
details.add(makeObjectDetail("service", myEncounter.getServiceProvider().getDisplay().getValue()));
|
details.put("service", myEncounter.getServiceProvider().getDisplay().getValue());
|
||||||
details.add(makeObjectDetail("type", myEncounter.getTypeFirstRep().getText().getValue()));
|
details.put("type", myEncounter.getTypeFirstRep().getText().getValue());
|
||||||
details.add(makeObjectDetail("status", myEncounter.getStatus().getValueAsString()));
|
details.put("status", myEncounter.getStatus().getValueAsString());
|
||||||
return details;
|
return details;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectDetail makeObjectDetail(String type, String value) {
|
|
||||||
ObjectDetail detail = new ObjectDetail();
|
|
||||||
if(type != null)
|
|
||||||
detail.setType(type);
|
|
||||||
if(value != null)
|
|
||||||
detail.setValue(value.getBytes());
|
|
||||||
return detail;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SecurityEventObjectSensitivityEnum getSensitivity() {
|
public SecurityEventObjectSensitivityEnum getSensitivity() {
|
||||||
//override this method to provide sensitivity information about the visit
|
//override this method to provide sensitivity information about the visit
|
||||||
|
|
|
@ -20,12 +20,11 @@ package ca.uhn.fhir.rest.server.audit;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Medication;
|
import ca.uhn.fhir.model.dstu.resource.Medication;
|
||||||
import ca.uhn.fhir.model.dstu.resource.MedicationPrescription;
|
import ca.uhn.fhir.model.dstu.resource.MedicationPrescription;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ObjectDetail;
|
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectSensitivityEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectSensitivityEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
||||||
|
|
||||||
|
@ -44,10 +43,10 @@ public class MedicationPrescriptionAuditor implements IResourceAuditor<Medicatio
|
||||||
if(myMedicationPrescription.getMedication() != null){
|
if(myMedicationPrescription.getMedication() != null){
|
||||||
Medication m = (Medication) myMedicationPrescription.getMedication().getResource();
|
Medication m = (Medication) myMedicationPrescription.getMedication().getResource();
|
||||||
if(m != null){
|
if(m != null){
|
||||||
return m.getName().getValue();
|
return "Medication Prescription: " + m.getName().getValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return myMedicationPrescription.getId().getValueAsString(); //if we don't have a medication name, use the id as the name
|
return "Medication Prescription: " + myMedicationPrescription.getId().getValueAsString(); //if we don't have a medication name, use the id as the name
|
||||||
}
|
}
|
||||||
return ""; //no medication prescription, nothing to do here
|
return ""; //no medication prescription, nothing to do here
|
||||||
}
|
}
|
||||||
|
@ -81,7 +80,7 @@ public class MedicationPrescriptionAuditor implements IResourceAuditor<Medicatio
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ObjectDetail> getDetail() {
|
public Map<String, String> getDetail() {
|
||||||
return null; //no additional details required for audit?
|
return null; //no additional details required for audit?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,11 @@ package ca.uhn.fhir.rest.server.audit;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Medication;
|
import ca.uhn.fhir.model.dstu.resource.Medication;
|
||||||
import ca.uhn.fhir.model.dstu.resource.MedicationStatement;
|
import ca.uhn.fhir.model.dstu.resource.MedicationStatement;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ObjectDetail;
|
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectSensitivityEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectSensitivityEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
||||||
|
|
||||||
|
@ -43,9 +42,9 @@ public class MedicationStatementAuditor implements IResourceAuditor<MedicationSt
|
||||||
if(myMedicationStatement != null){
|
if(myMedicationStatement != null){
|
||||||
Medication m = (Medication) myMedicationStatement.getMedication().getResource();
|
Medication m = (Medication) myMedicationStatement.getMedication().getResource();
|
||||||
if(m != null){
|
if(m != null){
|
||||||
return m.getName().getValue();
|
return "Medication Statement: " + m.getName().getValue();
|
||||||
}
|
}
|
||||||
return myMedicationStatement.getId().getValueAsString(); //if we don't have a medication name, use the id as the name
|
return "Medication Statement: " + myMedicationStatement.getId().getValueAsString(); //if we don't have a medication name, use the id as the name
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +78,7 @@ public class MedicationStatementAuditor implements IResourceAuditor<MedicationSt
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ObjectDetail> getDetail() {
|
public Map<String, String> getDetail() {
|
||||||
return null; //no additional details required for audit?
|
return null; //no additional details required for audit?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,13 +20,12 @@ package ca.uhn.fhir.rest.server.audit;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.util.HashMap;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ObjectDetail;
|
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectSensitivityEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectSensitivityEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum;
|
||||||
|
|
||||||
|
@ -52,7 +51,7 @@ public class PatientAuditor implements IResourceAuditor<Patient> {
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
if(myPatient != null){
|
if(myPatient != null){
|
||||||
return myPatient.getNameFirstRep().getText().getValue();
|
return "Patient: " + myPatient.getNameFirstRep().getText().getValue();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -76,22 +75,17 @@ public class PatientAuditor implements IResourceAuditor<Patient> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ObjectDetail> getDetail() {
|
public Map<String, String> getDetail() {
|
||||||
if(myPatient != null){
|
if(myPatient != null){
|
||||||
List<IdentifierDt> ids = myPatient.getIdentifier();
|
List<IdentifierDt> ids = myPatient.getIdentifier();
|
||||||
if(ids != null && !ids.isEmpty()){
|
if(ids != null && !ids.isEmpty()){
|
||||||
List<ObjectDetail> detailList = new ArrayList<ObjectDetail>(ids.size());
|
Map<String, String> detailMap = new HashMap<String, String>();
|
||||||
for(IdentifierDt id: ids){
|
for(IdentifierDt id: ids){
|
||||||
ObjectDetail detail = new ObjectDetail();
|
String key = id.getSystem().getValueAsString();
|
||||||
detail.setType(id.getSystem().getValueAsString());
|
String value = id.getValue().getValueAsString();
|
||||||
try {
|
detailMap.put(key, value);
|
||||||
detail.setValue(id.getValue().getValueAsString().getBytes("UTF-8"));
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
detail.setValue(id.getValue().getValueAsString().getBytes());
|
|
||||||
}
|
|
||||||
detailList.add(detail);
|
|
||||||
}
|
}
|
||||||
return detailList;
|
return detailMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -35,19 +36,23 @@ import org.apache.commons.lang3.NotImplementedException;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.BundleEntry;
|
import ca.uhn.fhir.model.api.BundleEntry;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.dstu.composite.CodingDt;
|
||||||
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent;
|
import ca.uhn.fhir.model.dstu.resource.SecurityEvent;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.Event;
|
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.Event;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ObjectDetail;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ObjectElement;
|
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ObjectElement;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.Participant;
|
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.Participant;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ParticipantNetwork;
|
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ParticipantNetwork;
|
||||||
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.Source;
|
import ca.uhn.fhir.model.dstu.resource.SecurityEvent.Source;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.ResourceTypeEnum;
|
|
||||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventActionEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventActionEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectLifecycleEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectLifecycleEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventOutcomeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventOutcomeEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SecurityEventParticipantNetworkTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventParticipantNetworkTypeEnum;
|
||||||
|
import ca.uhn.fhir.model.dstu.valueset.SecurityEventSourceTypeEnum;
|
||||||
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.UserInfoInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.UserInfoInterceptor;
|
||||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
@ -68,12 +73,20 @@ public class AuditingInterceptor extends InterceptorAdapter {
|
||||||
private IAuditDataStore myDataStore = null;
|
private IAuditDataStore myDataStore = null;
|
||||||
private Map<String, Class<? extends IResourceAuditor<? extends IResource>>> myAuditableResources = new HashMap<String, Class<? extends IResourceAuditor<? extends IResource>>>();
|
private Map<String, Class<? extends IResourceAuditor<? extends IResource>>> myAuditableResources = new HashMap<String, Class<? extends IResourceAuditor<? extends IResource>>>();
|
||||||
private boolean myClientParamsOptional = false;
|
private boolean myClientParamsOptional = false;
|
||||||
|
protected String mySiteId;
|
||||||
|
|
||||||
public AuditingInterceptor() {
|
public AuditingInterceptor() {
|
||||||
myClientParamsOptional = false;
|
mySiteId = "NONE";
|
||||||
|
myClientParamsOptional = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuditingInterceptor(boolean theClientParamsOptional){
|
public AuditingInterceptor(String theSiteId) {
|
||||||
|
mySiteId = theSiteId;
|
||||||
|
myClientParamsOptional = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuditingInterceptor(String theSiteId, boolean theClientParamsOptional){
|
||||||
|
mySiteId = theSiteId;
|
||||||
myClientParamsOptional = theClientParamsOptional;
|
myClientParamsOptional = theClientParamsOptional;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,8 +104,14 @@ public class AuditingInterceptor extends InterceptorAdapter {
|
||||||
auditEvent.setEvent(getEventInfo(theRequestDetails));
|
auditEvent.setEvent(getEventInfo(theRequestDetails));
|
||||||
//get user info from request if available
|
//get user info from request if available
|
||||||
Participant participant = getParticipant(theServletRequest);
|
Participant participant = getParticipant(theServletRequest);
|
||||||
if(participant == null) return true; //no user to audit - throws exception if client params are required
|
if(participant == null){
|
||||||
|
log.debug("No participant to audit");
|
||||||
|
return true; //no user to audit - throws exception if client params are required
|
||||||
|
}
|
||||||
|
List<Participant> participants = new ArrayList<SecurityEvent.Participant>(1);
|
||||||
|
participants.add(participant);
|
||||||
|
auditEvent.setParticipant(participants);
|
||||||
|
|
||||||
SecurityEventObjectLifecycleEnum lifecycle = mapResourceTypeToSecurityLifecycle(theRequestDetails.getResourceOperationType());
|
SecurityEventObjectLifecycleEnum lifecycle = mapResourceTypeToSecurityLifecycle(theRequestDetails.getResourceOperationType());
|
||||||
byte[] query = getQueryFromRequestDetails(theRequestDetails);
|
byte[] query = getQueryFromRequestDetails(theRequestDetails);
|
||||||
List<ObjectElement> auditableObjects = new ArrayList<SecurityEvent.ObjectElement>();
|
List<ObjectElement> auditableObjects = new ArrayList<SecurityEvent.ObjectElement>();
|
||||||
|
@ -101,8 +120,14 @@ public class AuditingInterceptor extends InterceptorAdapter {
|
||||||
ObjectElement auditableObject = getObjectElement(resource, lifecycle , query);
|
ObjectElement auditableObject = getObjectElement(resource, lifecycle , query);
|
||||||
if(auditableObject != null) auditableObjects.add(auditableObject);
|
if(auditableObject != null) auditableObjects.add(auditableObject);
|
||||||
}
|
}
|
||||||
if(!auditableObjects.isEmpty()) return true; //no PHI to audit
|
if(auditableObjects.isEmpty()){
|
||||||
|
log.debug("No auditable resources to audit.");
|
||||||
|
return true; //no PHI to audit
|
||||||
|
}else{
|
||||||
|
log.debug("Auditing " + auditableObjects.size() + " resources.");
|
||||||
|
}
|
||||||
auditEvent.setObject(auditableObjects);
|
auditEvent.setObject(auditableObjects);
|
||||||
|
auditEvent.setSource(getSourceElement(theServletRequest));
|
||||||
store(auditEvent);
|
store(auditEvent);
|
||||||
return true; //success
|
return true; //success
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
|
@ -126,15 +151,26 @@ public class AuditingInterceptor extends InterceptorAdapter {
|
||||||
|
|
||||||
//get user info from request if available
|
//get user info from request if available
|
||||||
Participant participant = getParticipant(theServletRequest);
|
Participant participant = getParticipant(theServletRequest);
|
||||||
if(participant == null) return true; //no user to audit - throws exception if client params are required
|
if(participant == null){
|
||||||
|
log.debug("No participant to audit");
|
||||||
|
return true; //no user to audit - throws exception if client params are required
|
||||||
|
}
|
||||||
|
List<Participant> participants = new ArrayList<SecurityEvent.Participant>(1);
|
||||||
|
participants.add(participant);
|
||||||
|
auditEvent.setParticipant(participants);
|
||||||
|
|
||||||
byte[] query = getQueryFromRequestDetails(theRequestDetails);
|
byte[] query = getQueryFromRequestDetails(theRequestDetails);
|
||||||
SecurityEventObjectLifecycleEnum lifecycle = mapResourceTypeToSecurityLifecycle(theRequestDetails.getResourceOperationType());
|
SecurityEventObjectLifecycleEnum lifecycle = mapResourceTypeToSecurityLifecycle(theRequestDetails.getResourceOperationType());
|
||||||
ObjectElement auditableObject = getObjectElement(theResponseObject, lifecycle , query);
|
ObjectElement auditableObject = getObjectElement(theResponseObject, lifecycle , query);
|
||||||
if(auditableObject == null) return true; //nothing to audit
|
if(auditableObject == null){
|
||||||
|
log.debug("No auditable resources to audit");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
List<ObjectElement> auditableObjects = new ArrayList<SecurityEvent.ObjectElement>(1);
|
List<ObjectElement> auditableObjects = new ArrayList<SecurityEvent.ObjectElement>(1);
|
||||||
auditableObjects.add(auditableObject);
|
auditableObjects.add(auditableObject);
|
||||||
auditEvent.setObject(auditableObjects);
|
auditEvent.setObject(auditableObjects);
|
||||||
|
auditEvent.setSource(getSourceElement(theServletRequest));
|
||||||
|
log.debug("Auditing one resource.");
|
||||||
store(auditEvent);
|
store(auditEvent);
|
||||||
return true;
|
return true;
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
|
@ -143,7 +179,6 @@ public class AuditingInterceptor extends InterceptorAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void store(SecurityEvent auditEvent) throws Exception {
|
protected void store(SecurityEvent auditEvent) throws Exception {
|
||||||
if(myDataStore == null) throw new InternalErrorException("No data store provided to persist audit events");
|
if(myDataStore == null) throw new InternalErrorException("No data store provided to persist audit events");
|
||||||
myDataStore.store(auditEvent);
|
myDataStore.store(auditEvent);
|
||||||
|
@ -182,7 +217,8 @@ public class AuditingInterceptor extends InterceptorAdapter {
|
||||||
protected ObjectElement getObjectElement(IResource resource, SecurityEventObjectLifecycleEnum lifecycle, byte[] query) throws InstantiationException, IllegalAccessException {
|
protected ObjectElement getObjectElement(IResource resource, SecurityEventObjectLifecycleEnum lifecycle, byte[] query) throws InstantiationException, IllegalAccessException {
|
||||||
|
|
||||||
String resourceType = resource.getResourceName();
|
String resourceType = resource.getResourceName();
|
||||||
if(myAuditableResources.containsKey(resourceType)){
|
if(myAuditableResources.containsKey(resourceType)){
|
||||||
|
log.debug("Found auditable resource of type: " + resourceType);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
IResourceAuditor<IResource> auditableResource = (IResourceAuditor<IResource>) myAuditableResources.get(resourceType).newInstance();
|
IResourceAuditor<IResource> auditableResource = (IResourceAuditor<IResource>) myAuditableResources.get(resourceType).newInstance();
|
||||||
auditableResource.setResource(resource);
|
auditableResource.setResource(resource);
|
||||||
|
@ -192,19 +228,44 @@ public class AuditingInterceptor extends InterceptorAdapter {
|
||||||
object.setLifecycle(lifecycle);
|
object.setLifecycle(lifecycle);
|
||||||
object.setQuery(query);
|
object.setQuery(query);
|
||||||
object.setName(auditableResource.getName());
|
object.setName(auditableResource.getName());
|
||||||
object.setIdentifier(auditableResource.getIdentifier());
|
object.setIdentifier((IdentifierDt) auditableResource.getIdentifier());
|
||||||
object.setType(auditableResource.getType());
|
object.setType(auditableResource.getType());
|
||||||
object.setDescription(auditableResource.getDescription());
|
object.setDescription(auditableResource.getDescription());
|
||||||
object.setDetail(auditableResource.getDetail());
|
Map<String, String> detailMap = auditableResource.getDetail();
|
||||||
object.setSensitivity(auditableResource.getSensitivity());
|
if(detailMap != null && !detailMap.isEmpty()){
|
||||||
|
List<ObjectDetail> details = new ArrayList<SecurityEvent.ObjectDetail>();
|
||||||
|
for(Entry<String, String> entry: detailMap.entrySet()){
|
||||||
|
ObjectDetail detail = makeObjectDetail(entry.getKey(), entry.getValue());
|
||||||
|
details.add(detail);
|
||||||
|
}
|
||||||
|
object.setDetail(details);
|
||||||
|
}
|
||||||
|
object.setSensitivity(auditableResource.getSensitivity());
|
||||||
return object;
|
return object;
|
||||||
}
|
}else{
|
||||||
}
|
log.debug("Resource is not auditable");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
log.debug("No auditor configured for resource type " + resourceType);
|
||||||
|
}
|
||||||
return null; //not something we care to audit
|
return null; //not something we care to audit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ObjectDetail makeObjectDetail(String type, String value) {
|
||||||
|
ObjectDetail detail = new ObjectDetail();
|
||||||
|
if(type != null)
|
||||||
|
detail.setType(type);
|
||||||
|
if(value != null)
|
||||||
|
detail.setValue(value.getBytes());
|
||||||
|
return detail;
|
||||||
|
}
|
||||||
|
|
||||||
protected Participant getParticipant(HttpServletRequest theServletRequest) throws InvalidRequestException, NotImplementedException {
|
protected Participant getParticipant(HttpServletRequest theServletRequest) throws InvalidRequestException, NotImplementedException {
|
||||||
if(theServletRequest.getHeader(Constants.HEADER_AUTHORIZATION) != null && theServletRequest.getHeader(Constants.HEADER_AUTHORIZATION).startsWith("OAuth")){
|
if(theServletRequest.getHeader(Constants.HEADER_AUTHORIZATION) != null && theServletRequest.getHeader(Constants.HEADER_AUTHORIZATION).startsWith("OAuth")){
|
||||||
|
if(myClientParamsOptional){
|
||||||
|
log.debug("OAuth request received but no auditing required.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
//TODO: get user info from token
|
//TODO: get user info from token
|
||||||
throw new NotImplementedException("OAuth user auditing not yet implemented.");
|
throw new NotImplementedException("OAuth user auditing not yet implemented.");
|
||||||
}else { //no auth or basic auth or anything else, use HTTP headers for user info
|
}else { //no auth or basic auth or anything else, use HTTP headers for user info
|
||||||
|
@ -224,7 +285,38 @@ public class AuditingInterceptor extends InterceptorAdapter {
|
||||||
network.setIdentifier(userIp);
|
network.setIdentifier(userIp);
|
||||||
return participant;
|
return participant;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Source getSourceElement(HttpServletRequest theServletRequest) {
|
||||||
|
if(theServletRequest.getHeader(Constants.HEADER_AUTHORIZATION) != null && theServletRequest.getHeader(Constants.HEADER_AUTHORIZATION).startsWith("OAuth")){
|
||||||
|
if(myClientParamsOptional) return null; //no auditing required
|
||||||
|
//TODO: get application info from token
|
||||||
|
throw new NotImplementedException("OAuth auditing not yet implemented.");
|
||||||
|
}else { //no auth or basic auth or anything else, use HTTP headers for audit info
|
||||||
|
String appId = theServletRequest.getHeader(UserInfoInterceptor.HEADER_APPLICATION_NAME);
|
||||||
|
Source source = new Source();
|
||||||
|
source.setIdentifier(appId);
|
||||||
|
source.setType(getAccessType(theServletRequest));
|
||||||
|
source.setSite(getSiteId(theServletRequest));
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected StringDt getSiteId(HttpServletRequest theServletRequest) {
|
||||||
|
return new StringDt(mySiteId); //override this method to pull the site id from the request info
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<CodingDt> getAccessType(HttpServletRequest theServletRequest) {
|
||||||
|
List<CodingDt> types = new ArrayList<CodingDt>();
|
||||||
|
if(theServletRequest.getHeader(Constants.HEADER_AUTHORIZATION) != null && theServletRequest.getHeader(Constants.HEADER_AUTHORIZATION).startsWith("OAuth")){
|
||||||
|
types.add(new CodingDt(SecurityEventSourceTypeEnum.USER_DEVICE.getSystem(), SecurityEventSourceTypeEnum.USER_DEVICE.getCode()));
|
||||||
|
}else{
|
||||||
|
String userId = theServletRequest.getHeader(UserInfoInterceptor.HEADER_USER_ID);
|
||||||
|
String appId = theServletRequest.getHeader(UserInfoInterceptor.HEADER_APPLICATION_NAME);
|
||||||
|
if (userId == null && appId != null) types.add(new CodingDt(SecurityEventSourceTypeEnum.APPLICATION_SERVER.getSystem(), SecurityEventSourceTypeEnum.APPLICATION_SERVER.getCode()));
|
||||||
|
else types.add(new CodingDt(SecurityEventSourceTypeEnum.USER_DEVICE.getSystem(), SecurityEventSourceTypeEnum.USER_DEVICE.getCode()));
|
||||||
|
}
|
||||||
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SecurityEventActionEnum mapResourceTypeToSecurityEventAction(RestfulOperationTypeEnum resourceOperationType) {
|
protected SecurityEventActionEnum mapResourceTypeToSecurityEventAction(RestfulOperationTypeEnum resourceOperationType) {
|
||||||
|
|
|
@ -201,7 +201,7 @@ public class ResourceWithExtensionsA extends BaseResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourceTypeEnum getResourceType() {
|
public String getResourceName() {
|
||||||
return null; //not implemented
|
return null; //not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,8 +108,8 @@ public class Patient extends BaseResource implements IResource {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourceTypeEnum getResourceType() {
|
public String getResourceName() {
|
||||||
return ResourceTypeEnum.PATIENT;
|
return Patient.class.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue