From 5f3a366ab05db42d0194224086b8c8b580a3eb6f Mon Sep 17 00:00:00 2001 From: lmds1 Date: Mon, 10 Nov 2014 18:09:11 -0500 Subject: [PATCH] updated IResourceAuditor interface --- .../interceptor/UserInfoInterceptor.java | 10 +- .../rest/server/audit/IResourceAuditor.java | 42 +++++- .../server/audit/DiagnosticReportAuditor.java | 27 ++-- .../rest/server/audit/EncounterAuditor.java | 32 ++--- .../audit/MedicationPrescriptionAuditor.java | 9 +- .../audit/MedicationStatementAuditor.java | 9 +- .../rest/server/audit/PatientAuditor.java | 24 ++-- .../interceptor/AuditingInterceptor.java | 124 +++++++++++++++--- .../fhir/context/ResourceWithExtensionsA.java | 2 +- .../java/ca/uhn/fhir/testmodel/Patient.java | 4 +- 10 files changed, 193 insertions(+), 90 deletions(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java index 12f75c0e512..db79d89f64b 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java @@ -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_NAME = "fhir-user-name"; - + public static final String HEADER_APPLICATION_NAME = "fhir-app-name"; + private String myUserId; private String myUserName; + private String myAppName; - public UserInfoInterceptor(String theUserId, String theUserName) { + public UserInfoInterceptor(String theUserId, String theUserName, String theAppName) { super(); myUserId = theUserId; myUserName = theUserName; + myAppName = theAppName; } @Override public void interceptRequest(HttpRequestBase theRequest) { 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 diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/audit/IResourceAuditor.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/audit/IResourceAuditor.java index b1a5ee02969..ff2d18badf9 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/audit/IResourceAuditor.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/audit/IResourceAuditor.java @@ -20,7 +20,7 @@ package ca.uhn.fhir.rest.server.audit; * #L% */ -import java.util.List; +import java.util.Map; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.base.composite.BaseIdentifierDt; @@ -29,17 +29,53 @@ import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectTypeEnum; public interface IResourceAuditor { - + + /** + * @return the resource to be audited + */ public T getResource(); + + /** + * @param resource the resource to be audited by this auditor + */ public void setResource(T resource); + /** + * @return true if this resource is to be audited, false otherwise + */ 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(); + + /** + * @return the identifier of the resource to be audited + */ public BaseIdentifierDt getIdentifier(); + + /** + * @return the SecurityEventObjectTypeEnum of this resource + */ public SecurityEventObjectTypeEnum getType(); + + /** + * @return a text description of the resource + */ public String getDescription(); - //public List 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 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(); + } diff --git a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/DiagnosticReportAuditor.java b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/DiagnosticReportAuditor.java index 15ab91acfaa..32a39c57125 100644 --- a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/DiagnosticReportAuditor.java +++ b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/DiagnosticReportAuditor.java @@ -20,12 +20,11 @@ package ca.uhn.fhir.rest.server.audit; * #L% */ -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import ca.uhn.fhir.model.dstu.composite.IdentifierDt; 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.SecurityEventObjectTypeEnum; @@ -41,7 +40,7 @@ public class DiagnosticReportAuditor implements IResourceAuditor getDetail() { - List details = new ArrayList(); - details.add(makeObjectDetail("dateIssued", myDiagnosticReport.getIssued().getValueAsString())); - details.add(makeObjectDetail("version", myDiagnosticReport.getId().getVersionIdPart())); + public Map getDetail() { + Map details = new HashMap(); + details.put("dateIssued", myDiagnosticReport.getIssued().getValueAsString()); + details.put("version", myDiagnosticReport.getId().getVersionIdPart()); return details; } @Override public SecurityEventObjectSensitivityEnum getSensitivity() { 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; - } - + } } diff --git a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/EncounterAuditor.java b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/EncounterAuditor.java index 9c905f6ae59..34ea305dd5e 100644 --- a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/EncounterAuditor.java +++ b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/EncounterAuditor.java @@ -20,12 +20,11 @@ package ca.uhn.fhir.rest.server.audit; * #L% */ -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import ca.uhn.fhir.model.dstu.composite.IdentifierDt; 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.SecurityEventObjectTypeEnum; @@ -54,7 +53,7 @@ public class EncounterAuditor implements IResourceAuditor { String id = myEncounter.getIdentifierFirstRep().getValue().getValue(); String system = myEncounter.getIdentifierFirstRep().getSystem().getValueAsString(); String service = myEncounter.getServiceProvider().getDisplay().getValue(); - return id + "/" + system + ": " + service; + return "Encounter: " + id + "/" + system + ": " + service; } return null; } @@ -79,31 +78,22 @@ public class EncounterAuditor implements IResourceAuditor { String status = myEncounter.getStatus().getValueAsString(); String startDate = myEncounter.getPeriod().getStart().getValueAsString(); String endDate = myEncounter.getPeriod().getEnd().getValueAsString(); - return type + ": " + status +", "+ startDate + " - " + endDate; + return "Encounter: " + type + ": " + status +", "+ startDate + " - " + endDate; } return null; } @Override - public List getDetail() { - List details = new ArrayList(); - details.add(makeObjectDetail("startDate", myEncounter.getPeriod().getStart().getValueAsString())); - details.add(makeObjectDetail("endDate", myEncounter.getPeriod().getEnd().getValueAsString())); - details.add(makeObjectDetail("service", myEncounter.getServiceProvider().getDisplay().getValue())); - details.add(makeObjectDetail("type", myEncounter.getTypeFirstRep().getText().getValue())); - details.add(makeObjectDetail("status", myEncounter.getStatus().getValueAsString())); + public Map getDetail() { + Map details = new HashMap(); + details.put("startDate", myEncounter.getPeriod().getStart().getValueAsString()); + details.put("endDate", myEncounter.getPeriod().getEnd().getValueAsString()); + details.put("service", myEncounter.getServiceProvider().getDisplay().getValue()); + details.put("type", myEncounter.getTypeFirstRep().getText().getValue()); + details.put("status", myEncounter.getStatus().getValueAsString()); 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 public SecurityEventObjectSensitivityEnum getSensitivity() { //override this method to provide sensitivity information about the visit diff --git a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/MedicationPrescriptionAuditor.java b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/MedicationPrescriptionAuditor.java index e16f4636df0..58122c3b0f8 100644 --- a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/MedicationPrescriptionAuditor.java +++ b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/MedicationPrescriptionAuditor.java @@ -20,12 +20,11 @@ package ca.uhn.fhir.rest.server.audit; * #L% */ -import java.util.List; +import java.util.Map; import ca.uhn.fhir.model.dstu.composite.IdentifierDt; import ca.uhn.fhir.model.dstu.resource.Medication; 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.SecurityEventObjectTypeEnum; @@ -44,10 +43,10 @@ public class MedicationPrescriptionAuditor implements IResourceAuditor getDetail() { + public Map getDetail() { return null; //no additional details required for audit? } diff --git a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/MedicationStatementAuditor.java b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/MedicationStatementAuditor.java index eff83ff0c5c..3f707c66a27 100644 --- a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/MedicationStatementAuditor.java +++ b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/MedicationStatementAuditor.java @@ -20,12 +20,11 @@ package ca.uhn.fhir.rest.server.audit; * #L% */ -import java.util.List; +import java.util.Map; import ca.uhn.fhir.model.dstu.composite.IdentifierDt; import ca.uhn.fhir.model.dstu.resource.Medication; 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.SecurityEventObjectTypeEnum; @@ -43,9 +42,9 @@ public class MedicationStatementAuditor implements IResourceAuditor getDetail() { + public Map getDetail() { return null; //no additional details required for audit? } diff --git a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/PatientAuditor.java b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/PatientAuditor.java index a882b4f6db7..ea7d0fc1f34 100644 --- a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/PatientAuditor.java +++ b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/audit/PatientAuditor.java @@ -20,13 +20,12 @@ package ca.uhn.fhir.rest.server.audit; * #L% */ -import java.io.UnsupportedEncodingException; -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.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.SecurityEventObjectTypeEnum; @@ -52,7 +51,7 @@ public class PatientAuditor implements IResourceAuditor { @Override public String getName() { if(myPatient != null){ - return myPatient.getNameFirstRep().getText().getValue(); + return "Patient: " + myPatient.getNameFirstRep().getText().getValue(); } return null; } @@ -76,22 +75,17 @@ public class PatientAuditor implements IResourceAuditor { } @Override - public List getDetail() { + public Map getDetail() { if(myPatient != null){ List ids = myPatient.getIdentifier(); if(ids != null && !ids.isEmpty()){ - List detailList = new ArrayList(ids.size()); + Map detailMap = new HashMap(); for(IdentifierDt id: ids){ - ObjectDetail detail = new ObjectDetail(); - detail.setType(id.getSystem().getValueAsString()); - try { - detail.setValue(id.getValue().getValueAsString().getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - detail.setValue(id.getValue().getValueAsString().getBytes()); - } - detailList.add(detail); + String key = id.getSystem().getValueAsString(); + String value = id.getValue().getValueAsString(); + detailMap.put(key, value); } - return detailList; + return detailMap; } } diff --git a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/interceptor/AuditingInterceptor.java b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/interceptor/AuditingInterceptor.java index 6a6e13f93a7..3e902a3bc60 100644 --- a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/interceptor/AuditingInterceptor.java +++ b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/interceptor/AuditingInterceptor.java @@ -26,6 +26,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; 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.BundleEntry; 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.resource.SecurityEvent; 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.Participant; import ca.uhn.fhir.model.dstu.resource.SecurityEvent.ParticipantNetwork; 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.SecurityEventActionEnum; import ca.uhn.fhir.model.dstu.valueset.SecurityEventObjectLifecycleEnum; import ca.uhn.fhir.model.dstu.valueset.SecurityEventOutcomeEnum; 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.method.RequestDetails; import ca.uhn.fhir.rest.server.Constants; @@ -68,12 +73,20 @@ public class AuditingInterceptor extends InterceptorAdapter { private IAuditDataStore myDataStore = null; private Map>> myAuditableResources = new HashMap>>(); private boolean myClientParamsOptional = false; + protected String mySiteId; 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; } @@ -91,8 +104,14 @@ public class AuditingInterceptor extends InterceptorAdapter { auditEvent.setEvent(getEventInfo(theRequestDetails)); //get user info from request if available 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 participants = new ArrayList(1); + participants.add(participant); + auditEvent.setParticipant(participants); + SecurityEventObjectLifecycleEnum lifecycle = mapResourceTypeToSecurityLifecycle(theRequestDetails.getResourceOperationType()); byte[] query = getQueryFromRequestDetails(theRequestDetails); List auditableObjects = new ArrayList(); @@ -101,8 +120,14 @@ public class AuditingInterceptor extends InterceptorAdapter { ObjectElement auditableObject = getObjectElement(resource, lifecycle , query); 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.setSource(getSourceElement(theServletRequest)); store(auditEvent); return true; //success }catch(Exception e){ @@ -126,15 +151,26 @@ public class AuditingInterceptor extends InterceptorAdapter { //get user info from request if available 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 participants = new ArrayList(1); + participants.add(participant); + auditEvent.setParticipant(participants); byte[] query = getQueryFromRequestDetails(theRequestDetails); SecurityEventObjectLifecycleEnum lifecycle = mapResourceTypeToSecurityLifecycle(theRequestDetails.getResourceOperationType()); 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 auditableObjects = new ArrayList(1); auditableObjects.add(auditableObject); auditEvent.setObject(auditableObjects); + auditEvent.setSource(getSourceElement(theServletRequest)); + log.debug("Auditing one resource."); store(auditEvent); return true; }catch(Exception e){ @@ -143,7 +179,6 @@ public class AuditingInterceptor extends InterceptorAdapter { } } - protected void store(SecurityEvent auditEvent) throws Exception { if(myDataStore == null) throw new InternalErrorException("No data store provided to persist audit events"); myDataStore.store(auditEvent); @@ -182,7 +217,8 @@ public class AuditingInterceptor extends InterceptorAdapter { protected ObjectElement getObjectElement(IResource resource, SecurityEventObjectLifecycleEnum lifecycle, byte[] query) throws InstantiationException, IllegalAccessException { String resourceType = resource.getResourceName(); - if(myAuditableResources.containsKey(resourceType)){ + if(myAuditableResources.containsKey(resourceType)){ + log.debug("Found auditable resource of type: " + resourceType); @SuppressWarnings("unchecked") IResourceAuditor auditableResource = (IResourceAuditor) myAuditableResources.get(resourceType).newInstance(); auditableResource.setResource(resource); @@ -192,19 +228,44 @@ public class AuditingInterceptor extends InterceptorAdapter { object.setLifecycle(lifecycle); object.setQuery(query); object.setName(auditableResource.getName()); - object.setIdentifier(auditableResource.getIdentifier()); + object.setIdentifier((IdentifierDt) auditableResource.getIdentifier()); object.setType(auditableResource.getType()); object.setDescription(auditableResource.getDescription()); - object.setDetail(auditableResource.getDetail()); - object.setSensitivity(auditableResource.getSensitivity()); + Map detailMap = auditableResource.getDetail(); + if(detailMap != null && !detailMap.isEmpty()){ + List details = new ArrayList(); + for(Entry entry: detailMap.entrySet()){ + ObjectDetail detail = makeObjectDetail(entry.getKey(), entry.getValue()); + details.add(detail); + } + object.setDetail(details); + } + object.setSensitivity(auditableResource.getSensitivity()); 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 } + 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 { 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 throw new NotImplementedException("OAuth user auditing not yet implemented."); }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); 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 getAccessType(HttpServletRequest theServletRequest) { + List types = new ArrayList(); + 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) { diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ResourceWithExtensionsA.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ResourceWithExtensionsA.java index c7198df4b32..08ec74f9725 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ResourceWithExtensionsA.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ResourceWithExtensionsA.java @@ -201,7 +201,7 @@ public class ResourceWithExtensionsA extends BaseResource { } @Override - public ResourceTypeEnum getResourceType() { + public String getResourceName() { return null; //not implemented } diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/testmodel/Patient.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/testmodel/Patient.java index 647b54b1788..86f776c7e5d 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/testmodel/Patient.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/testmodel/Patient.java @@ -108,8 +108,8 @@ public class Patient extends BaseResource implements IResource { @Override - public ResourceTypeEnum getResourceType() { - return ResourceTypeEnum.PATIENT; + public String getResourceName() { + return Patient.class.getName(); }