/// <summary> /// Audits the generic error. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <param name="eventTypeCode">The event type code.</param> /// <param name="eventIdentifierType">Type of the event identifier.</param> /// <param name="exception">The exception.</param> public override void AuditGenericError(OutcomeIndicator outcomeIndicator, AuditCode eventTypeCode, EventIdentifierType eventIdentifierType, Exception exception) { var audit = this.CreateBaseAudit(ActionType.Execute, eventTypeCode, eventIdentifierType, outcomeIndicator); audit.AuditableObjects.Add(new AuditableObject { IDTypeCode = AuditableObjectIdType.Uri, ObjectId = this.Context.Request.Url.ToString(), Role = AuditableObjectRole.Resource, Type = AuditableObjectType.SystemObject }); if (exception != null) { var auditableObject = new AuditableObject { IDTypeCode = AuditableObjectIdType.Custom, ObjectId = exception.GetHashCode().ToString(), Role = AuditableObjectRole.Resource, Type = AuditableObjectType.Other }; auditableObject.ObjectData.Add(new ObjectDataExtension(exception.GetType().Name, ObjectToByteArray(new Error(exception)))); audit.AuditableObjects.Add(auditableObject); } AuditService.SendAudit(audit); }
/// <summary> /// Create audit data /// </summary> public AuditData CreateAuditData(string itiName, ActionType action, OutcomeIndicator outcome, Hl7MessageReceivedEventArgs msgEvent, RegistryQueryResult result) { // Create the call to the other create audit data message by constructing the list of disclosed identifiers List <VersionedDomainIdentifier> vids = new List <VersionedDomainIdentifier>(result.Results.Count); foreach (var res in result.Results) { if (res == null) { continue; } var subj = res.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person; if (subj == null) { continue; } vids.Add(new VersionedDomainIdentifier() { Domain = this.m_configService.OidRegistrar.GetOid("CR_CID").Oid, Identifier = subj.Id.ToString() }); } return(CreateAuditData(itiName, action, outcome, msgEvent, vids)); }
/// <summary> /// Audits the creation of an entity. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <param name="entity">The entity.</param> public void AuditCreateEntity(OutcomeIndicator outcomeIndicator, Entity entity) { var audit = base.CreateBaseAudit(ActionType.Create, CreateEntityAuditCode, EventIdentifierType.ApplicationActivity, outcomeIndicator); if (entity != null) { var auditableObjectType = AuditableObjectType.Other; if (entity is Organization) { auditableObjectType = AuditableObjectType.Organization; } else if (entity is Provider || entity is Person) { auditableObjectType = AuditableObjectType.Person; } base.AddObjectInfo(audit, AuditableObjectIdType.Custom, AuditableObjectLifecycle.Creation, AuditableObjectRole.Resource, auditableObjectType, "Key", "Key", true, new { Key = entity.Key.ToString(), entity.CreationTime, entity.CreatedByKey, entity.ClassConceptKey }); } AuditService.SendAudit(audit); }
/// <summary> /// Audit that the audit log was used /// </summary> /// <param name="action"></param> /// <param name="outcome"></param> /// <param name="query"></param> /// <param name="auditIds"></param> public static void AuditAuditLogUsed(ActionType action, OutcomeIndicator outcome, String query, params Guid[] auditIds) { traceSource.TraceVerbose("Create AuditLogUsed audit"); AuditData audit = new AuditData(DateTime.Now, action, outcome, EventIdentifierType.SecurityAlert, CreateAuditActionCode(EventTypeCodes.AuditLogUsed)); // User actors AddDeviceActor(audit); AddUserActor(audit); AddSenderDeviceActor(audit); // Add objects to which the thing was done audit.AuditableObjects = auditIds.Select(o => new AuditableObject() { IDTypeCode = AuditableObjectIdType.ReportNumber, LifecycleType = action == ActionType.Delete ? AuditableObjectLifecycle.PermanentErasure : AuditableObjectLifecycle.Disclosure, ObjectId = o.ToString(), Role = AuditableObjectRole.SecurityResource, Type = AuditableObjectType.SystemObject }).ToList(); if (!String.IsNullOrEmpty(query)) { audit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.SearchCritereon, LifecycleType = AuditableObjectLifecycle.Access, QueryData = query, Role = AuditableObjectRole.Query, Type = AuditableObjectType.SystemObject }); } SendAudit(audit); }
/// <summary> /// Send the PDQ audit /// </summary> public static void SendPDQAudit(NHapi.Model.V25.Message.QBP_Q21 request, NHapi.Model.V25.Message.RSP_K21 response) { OutcomeIndicator outcome = OutcomeIndicator.Success; if (!response.MSA.AcknowledgmentCode.Value.EndsWith("A")) { outcome = OutcomeIndicator.EpicFail; } var audit = CreateAudit(ActionType.Execute, outcome, EventIdentifierType.Query, new CodeValue <string>("ITI-21", "IHE Transactions") { DisplayName = "Patient Demographcis Query" }, request, ConfigurationManager.AppSettings["crEndpoint"]); audit.AuditableObjects = new List <AuditableObject>(); // Results found if (response.QAK.QueryResponseStatus.Value == "OK") { for (int i = 0; i < response.QUERY_RESPONSERepetitionsUsed; i++) { audit.AuditableObjects.Add( new AuditableObject() { Type = AuditableObjectType.Person, TypeSpecified = true, Role = AuditableObjectRole.Patient, RoleSpecified = true, LifecycleType = AuditableObjectLifecycle.Export, IDTypeCode = new CodeValue <AuditableObjectIdType>(AuditableObjectIdType.PatientNumber), ObjectId = string.Format("{0}^^^&{1}&ISO", response.GetQUERY_RESPONSE(i).PID.GetPatientIdentifierList(0).IDNumber.Value, response.GetQUERY_RESPONSE(i).PID.GetPatientIdentifierList(0).AssigningAuthority.UniversalID.Value) } ); } } // Query parameters audit.AuditableObjects.Add(new AuditableObject() { Type = AuditableObjectType.SystemObject, TypeSpecified = true, Role = AuditableObjectRole.Query, RoleSpecified = true, ObjectId = request.QPD.QueryTag.Value, IDTypeCode = new CodeValue <AuditableObjectIdType>(AuditableObjectIdType.ITI21), ObjectSpecChoice = ObjectDataChoiceType.ParticipantObjectQuery, ObjectSpec = Convert.ToBase64String(Encoding.UTF8.GetBytes(new PipeParser().Encode(request))), ObjectDetail = new List <ObjectDetailType>() { new ObjectDetailType() { Type = "MSH-10", Value = System.Text.Encoding.UTF8.GetBytes(request.MSH.MessageControlID.Value) } } }); SendAudit(audit); }
/// <summary> /// Initializes a new instance of the <see cref="AuditData"/> class. /// </summary> /// <param name="timeStamp">The time stamp.</param> /// <param name="actionCode">The action code.</param> /// <param name="outcome">The outcome.</param> /// <param name="eventIdentifier">The event identifier.</param> /// <param name="eventTypeCode">The event type code.</param> public AuditData(DateTimeOffset timeStamp, ActionType actionCode, OutcomeIndicator outcome, EventIdentifierType eventIdentifier, AuditCode eventTypeCode) : this() { this.Timestamp = timeStamp; this.ActionCode = actionCode; this.Outcome = outcome; this.EventIdentifier = eventIdentifier; this.EventTypeCode = eventTypeCode; this.Actors = new List <AuditActorData>(); this.AuditableObjects = new List <AuditableObject>(); }
/// <summary> /// Audits the change password. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <param name="identityName">Name of the identity.</param> /// <param name="deviceId">The device identifier.</param> /// <exception cref="System.NotImplementedException"></exception> public void AuditChangePassword(OutcomeIndicator outcomeIndicator, string identityName, string deviceId) { var audit = CreateBaseAudit(ActionType.Execute, CreateAuditCode(EventTypeCode.UserSecurityChanged), EventIdentifierType.UserAuthentication, outcomeIndicator); audit.Actors.Add(new AuditActorData { NetworkAccessPointId = deviceId, NetworkAccessPointType = NetworkAccessPointType.MachineName, UserIsRequestor = true, UserName = identityName }); AuditService.SendAudit(audit); }
/// <summary> /// Audits the query security entity. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <param name="securityEntities">The security entities.</param> public void AuditQuerySecurityEntity(OutcomeIndicator outcomeIndicator, IEnumerable <SecurityApplication> securityEntities) { var audit = base.CreateSecurityResourceQueryAudit(this.QuerySecurityEntityAuditCode, outcomeIndicator); if (securityEntities?.Any() == true) { base.AddObjectInfoEx(audit, AuditableObjectIdType.UserIdentifier, AuditableObjectLifecycle.Disclosure, AuditableObjectRole.SecurityResource, AuditableObjectType.Other, "Key", "Name", true, securityEntities.Select(s => new { Key = s.Key.ToString(), s.CreationTime, s.Name }).AsEnumerable()); } AuditService.SendAudit(audit); }
/// <summary> /// Audits the create security entity. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <param name="securityEntity">The security entity.</param> public void AuditCreateSecurityEntity(OutcomeIndicator outcomeIndicator, SecurityApplication securityEntity) { var audit = base.CreateSecurityResourceCreateAudit(securityEntity, this.CreateSecurityEntityAuditCode, outcomeIndicator); if (securityEntity != null) { base.AddObjectInfo(audit, AuditableObjectIdType.UserIdentifier, AuditableObjectLifecycle.Creation, AuditableObjectRole.SecurityResource, AuditableObjectType.Other, "Key", "Name", true, new { Key = securityEntity.Key.Value, securityEntity.CreationTime, securityEntity.Name }); } AuditService.SendAudit(audit); }
/// <summary> /// Audits the query of entities. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <param name="entities">The entities.</param> public void AuditQueryEntity(OutcomeIndicator outcomeIndicator, IEnumerable <Entity> entities) { var audit = base.CreateBaseAudit(ActionType.Read, QueryEntityAuditCode, EventIdentifierType.ApplicationActivity, outcomeIndicator); if (entities?.Any() == true) { base.AddObjectInfoEx(audit, AuditableObjectIdType.Custom, AuditableObjectLifecycle.Disclosure, AuditableObjectRole.Resource, AuditableObjectType.Other, "Key", "Key", true, entities.Select(e => new { Key = e.Key.ToString(), e.CreationTime, e.CreatedByKey, e.ClassConceptKey })); } AuditService.SendAudit(audit); }
/// <summary> /// Audits the delete security entity. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <param name="securityEntity">The security entity.</param> public void AuditDeleteSecurityEntity(OutcomeIndicator outcomeIndicator, SecurityDevice securityEntity) { var audit = base.CreateSecurityResourceDeleteAudit(securityEntity, this.DeleteSecurityEntityAuditCode, outcomeIndicator); if (securityEntity != null) { base.AddObjectInfo(audit, AuditableObjectIdType.UserIdentifier, AuditableObjectLifecycle.LogicalDeletion, AuditableObjectRole.SecurityResource, AuditableObjectType.Other, "Key", "Name", true, new { Key = securityEntity.Key.ToString(), securityEntity.CreationTime, securityEntity.ObsoletionTime, ObsoletedByKey = securityEntity.ObsoletedByKey.ToString(), securityEntity.Name }); } AuditService.SendAudit(audit); }
/// <summary> /// Send audit merge /// </summary> protected virtual void SendAuditMerge(OutcomeIndicator outcome, IMessage message, RecordMergeResult recordMergeResult) { if (recordMergeResult != null) { AuditUtil.AuditDelete(outcome, "ADT^A40", new Patient() { Key = recordMergeResult.Replaced.First() }); AuditUtil.AuditUpdate(outcome, "ADT^A40", new Patient() { Key = recordMergeResult.Survivors.First() }); } else { AuditUtil.AuditUpdate <IdentifiedData>(outcome, "ADT^A40"); } }
/// <summary> /// Send a pix audit /// </summary> public static void SendPIXAudit(NHapi.Model.V25.Message.ADT_A01 request, NHapi.Model.V231.Message.ACK response) { ActionType act = ActionType.Create; OutcomeIndicator outcome = OutcomeIndicator.Success; if (request.MSH.MessageType.TriggerEvent.Value == "A08") { act = ActionType.Update; } if (!response.MSA.AcknowledgementCode.Value.EndsWith("A")) { outcome = OutcomeIndicator.EpicFail; } var audit = CreateAudit(act, outcome, EventIdentifierType.PatientRecord, new CodeValue <string>("ITI-8", "IHE Transactions") { DisplayName = "Patient Identity Feed" }, request, ConfigurationManager.AppSettings["crEndpoint"]); audit.AuditableObjects = new List <AuditableObject>() { new AuditableObject() { Type = AuditableObjectType.Person, TypeSpecified = true, Role = AuditableObjectRole.Patient, RoleSpecified = true, LifecycleType = AuditableObjectLifecycle.Export, IDTypeCode = new CodeValue <AuditableObjectIdType>(AuditableObjectIdType.PatientNumber), ObjectId = string.Format("{0}^^^&{1}&ISO", request.PID.GetPatientIdentifierList(0).IDNumber.Value, request.PID.GetPatientIdentifierList(0).AssigningAuthority.UniversalID.Value), ObjectDetail = new List <ObjectDetailType>() { new ObjectDetailType() { Type = "MSH-10", Value = System.Text.Encoding.UTF8.GetBytes(request.MSH.MessageControlID.Value) } } } }; SendAudit(audit); }
/// <summary> /// Audits the update security entity. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <param name="securityEntity">The security entity.</param> public void AuditUpdateSecurityEntity(OutcomeIndicator outcomeIndicator, SecurityUser securityEntity) { var audit = this.CreateSecurityResourceUpdateAudit(securityEntity, this.UpdateSecurityEntityAuditCode, outcomeIndicator); if (securityEntity != null) { base.AddObjectInfo(audit, AuditableObjectIdType.UserIdentifier, AuditableObjectLifecycle.Creation, AuditableObjectRole.SecurityResource, AuditableObjectType.Other, "Key", "Name", true, new { Key = securityEntity.Key.ToString(), Name = securityEntity.UserName, securityEntity.CreationTime, securityEntity.UpdatedTime, UpdatedByKey = securityEntity.UpdatedByKey.ToString(), securityEntity.Email, securityEntity.PhoneNumber }); } AuditService.SendAudit(audit); }
/// <summary> /// Audit an operation that was exceuted /// </summary> private void AuditOperationAction(string resourceType, string operationName, OutcomeIndicator outcome, params Resource[] objects) { var audit = new AuditData(DateTime.Now, ActionType.Execute, outcome, EventIdentifierType.ApplicationActivity, new AuditCode(Hl7.Fhir.Utility.EnumUtility.GetLiteral(SystemRestfulInteraction.Batch), "http://hl7.org/fhir/ValueSet/system-restful-interaction")); AuditUtil.AddLocalDeviceActor(audit); AuditUtil.AddUserActor(audit); var handler = ExtensionUtil.GetOperation(resourceType, operationName); audit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.Uri, ObjectId = handler?.Uri.ToString() ?? $"urn:uuid:{Guid.Empty}", QueryData = RestOperationContext.Current?.IncomingRequest.Url.ToString(), ObjectData = RestOperationContext.Current?.IncomingRequest.Headers.AllKeys.Select(o => new ObjectDataExtension(o, RestOperationContext.Current.IncomingRequest.Headers.Get(o))).ToList(), Role = AuditableObjectRole.Job, Type = AuditableObjectType.SystemObject }); audit.AuditableObjects.AddRange(objects.SelectMany(o => this.CreateAuditObjects(o, AuditableObjectLifecycle.NotSet))); AuditUtil.SendAudit(audit); }
/// <summary> /// Append the outcome indicator to the audit /// </summary> public static AuditData WithOutcome(this AuditData me, OutcomeIndicator outcome) { me.Outcome = outcome; return(me); }
/// <summary> /// A utility which can be used to send a data audit /// </summary> public static void AuditDataAction <TData>(EventTypeCodes typeCode, ActionType action, AuditableObjectLifecycle lifecycle, EventIdentifierType eventType, OutcomeIndicator outcome, String queryPerformed, params TData[] data) where TData : IdentifiedData { AuditCode eventTypeId = CreateAuditActionCode(typeCode); AuditData audit = new AuditData(DateTime.Now, action, outcome, eventType, eventTypeId); AddDeviceActor(audit); AddUserActor(audit); // Objects audit.AuditableObjects = data.Select(o => { var idTypeCode = AuditableObjectIdType.Custom; var roleCode = AuditableObjectRole.Resource; var objType = AuditableObjectType.Other; if (o is Patient) { idTypeCode = AuditableObjectIdType.PatientNumber; roleCode = AuditableObjectRole.Patient; objType = AuditableObjectType.Person; } else if (o is UserEntity || o is Provider) { idTypeCode = AuditableObjectIdType.UserIdentifier; objType = AuditableObjectType.Person; roleCode = AuditableObjectRole.Provider; } else if (o is Entity) { idTypeCode = AuditableObjectIdType.EnrolleeNumber; } else if (o is Act) { idTypeCode = AuditableObjectIdType.EncounterNumber; roleCode = AuditableObjectRole.Report; } else if (o is SecurityUser) { idTypeCode = AuditableObjectIdType.UserIdentifier; roleCode = AuditableObjectRole.SecurityUser; objType = AuditableObjectType.SystemObject; } return(new AuditableObject() { IDTypeCode = idTypeCode, CustomIdTypeCode = idTypeCode == AuditableObjectIdType.Custom ? new AuditCode(o.GetType().Name, "OpenIZTable") : null, LifecycleType = lifecycle, ObjectId = o.Key?.ToString(), Role = roleCode, Type = objType }); }).ToList(); // Query performed if (!String.IsNullOrEmpty(queryPerformed)) { audit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.SearchCritereon, LifecycleType = AuditableObjectLifecycle.Access, ObjectId = typeof(TData).Name, QueryData = queryPerformed, Role = AuditableObjectRole.Query, Type = AuditableObjectType.SystemObject }); } AddAncillaryObject(audit); SendAudit(audit); }
/// <summary> /// Creates the base audit. /// </summary> /// <param name="actionType">Type of the action.</param> /// <param name="eventTypeCode">The event type code.</param> /// <param name="eventIdentifierType">Type of the event identifier.</param> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <returns>Returns the created base audit data.</returns> protected override AuditData CreateBaseAudit(ActionType actionType, AuditCode eventTypeCode, EventIdentifierType eventIdentifierType, OutcomeIndicator outcomeIndicator) { var audit = base.CreateBaseAudit(actionType, eventTypeCode, eventIdentifierType, outcomeIndicator); var remoteIp = GetLocalIPAddress(); try { // attempt to get the remote IP address remoteIp = this.Context.Request.ServerVariables["REMOTE_ADDR"]; } catch (Exception e) { Trace.TraceError($"Unable to retrieve remote IP address for auditing purposes: {e}"); } var userIdentifier = string.Empty; try { userIdentifier = this.Context.Request.Url.Host; } catch (Exception e) { Trace.TraceError($"Unable to retrieve request host URL for auditing purposes: {e}"); } // add the receiver audit.Actors.Add(new AuditActorData { UserName = Environment.UserName, UserIdentifier = userIdentifier, NetworkAccessPointId = Dns.GetHostName(), NetworkAccessPointType = NetworkAccessPointType.MachineName, AlternativeUserId = Process.GetCurrentProcess().Id.ToString(), ActorRoleCode = new List <AuditCode> { new AuditCode("110152", "DCM") } }); // add the sender audit.Actors.Add(new AuditActorData { UserIdentifier = remoteIp, NetworkAccessPointId = remoteIp, NetworkAccessPointType = NetworkAccessPointType.IPAddress, ActorRoleCode = new List <AuditCode> { new AuditCode("110153", "DCM") }, UserIsRequestor = true }); // add the user if this is an authenticated request if (this.Context.User?.Identity?.IsAuthenticated == true) { audit.Actors.Add(new AuditActorData { UserIdentifier = this.Context.User.Identity.Name, UserIsRequestor = true, NetworkAccessPointId = remoteIp, NetworkAccessPointType = NetworkAccessPointType.IPAddress, ActorRoleCode = new List <AuditCode> { new AuditCode("6", "AuditableObjectRole") } }); } else { // add the anonymous actor if the request isn't authenticated audit.Actors.Add(new AuditActorData { UserIdentifier = "Anonymous", UserIsRequestor = true, NetworkAccessPointId = remoteIp, NetworkAccessPointType = NetworkAccessPointType.IPAddress, ActorRoleCode = new List <AuditCode> { new AuditCode("6", "AuditableObjectRole") } }); } try { if (outcomeIndicator != OutcomeIndicator.Success) { // add the object detail using (var memoryStream = new MemoryStream()) { var detail = new ObjectDataExtension { Key = "HTTPMessage" }; using (var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8)) { streamWriter.WriteLine("<?xml version=\"1.0\"?><Request><![CDATA["); streamWriter.WriteLine("{0} {1} HTTP/1.1", this.Context.Request.HttpMethod, this.Context.Request.Url); for (var i = 0; i < this.Context.Request.Headers.Keys.Count; i++) { streamWriter.WriteLine("{0} : {1}", this.Context.Request.Headers.Keys[i], this.Context.Request.Headers[i]); } // Only output if request is not sensitive if (!this.IsRequestSensitive) { using (var sr = new StreamReader(this.Context.Request.InputStream)) { streamWriter.WriteLine("\r\n{0}", sr.ReadToEnd()); } } else { streamWriter.WriteLine("*********** SENSITIVE REQUEST REDACTED ***********"); } streamWriter.WriteLine("]]></Request>"); streamWriter.Flush(); detail.Value = memoryStream.GetBuffer().Take((int)memoryStream.Length).ToArray(); } var auditableObject = new AuditableObject { IDTypeCode = AuditableObjectIdType.Uri, ObjectId = this.Context.Request.Url.ToString(), Role = AuditableObjectRole.Query, Type = AuditableObjectType.SystemObject }; auditableObject.ObjectData.Add(detail); audit.AuditableObjects.Add(auditableObject); } } } catch (Exception e) { Trace.TraceError($"Unable to add object detail to audit message: {e}"); } return(audit); }
/// <summary> /// Audits the generic error. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <param name="eventTypeCode">The event type code.</param> /// <param name="eventIdentifierType">Type of the event identifier.</param> /// <param name="exception">The exception.</param> public override void AuditGenericError(OutcomeIndicator outcomeIndicator, EventTypeCode eventTypeCode, EventIdentifierType eventIdentifierType, Exception exception) { this.AuditGenericError(outcomeIndicator, CreateAuditCode(eventTypeCode), eventIdentifierType, exception); }
/// <summary> /// Creates the base audit. /// </summary> /// <param name="actionType">Type of the action.</param> /// <param name="eventTypeCode">The event type code.</param> /// <param name="eventIdentifierType">Type of the event identifier.</param> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <returns>Returns the created base audit data.</returns> protected virtual AuditData CreateBaseAudit(ActionType actionType, AuditCode eventTypeCode, EventIdentifierType eventIdentifierType, OutcomeIndicator outcomeIndicator) { var audit = CreateBaseAudit(actionType, eventTypeCode, eventIdentifierType); audit.Outcome = outcomeIndicator; return(audit); }
/// <summary> /// Create audit data /// </summary> internal AuditData CreateAuditData(string itiName, ActionType action, OutcomeIndicator outcome, Hl7MessageReceivedEventArgs msgEvent, List <VersionedDomainIdentifier> identifiers) { // Audit data AuditData retVal = null; AuditableObjectLifecycle lifecycle = AuditableObjectLifecycle.Access; // Get the config service ISystemConfigurationService config = Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; Terser terser = new Terser(msgEvent.Message); // Source and dest string sourceData = String.Format("{0}|{1}", terser.Get("/MSH-3"), terser.Get("/MSH-4")), destData = String.Format("{0}|{1}", terser.Get("/MSH-5"), terser.Get("/MSH-6")); switch (itiName) { case "ITI-21": { retVal = new AuditData(DateTime.Now, action, outcome, EventIdentifierType.Query, new CodeValue(itiName, "IHE Transactions") { DisplayName = "Patient Demographics Query" }); // Audit actor for Patient Identity Source retVal.Actors.Add(new AuditActorData() { UserIsRequestor = true, UserIdentifier = sourceData, ActorRoleCode = new List <CodeValue>() { new CodeValue("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointId = msgEvent.SolicitorEndpoint.Host, NetworkAccessPointType = msgEvent.SolicitorEndpoint.HostNameType == UriHostNameType.Dns ? NetworkAccessPointType.MachineName : NetworkAccessPointType.IPAddress }); // Add query parameters retVal.AuditableObjects.Add( new AuditableObject() { IDTypeCode = AuditableObjectIdType.Custom, CustomIdTypeCode = new CodeValue(itiName, "IHE Transactions") { DisplayName = "Patient Demographics Query" }, QueryData = Convert.ToBase64String(CreateMessageSerialized(msgEvent.Message)), Type = AuditableObjectType.SystemObject, Role = AuditableObjectRole.Query, ObjectId = terser.Get("/QPD-2"), ObjectData = new Dictionary <string, byte[]>() { { "MSH-10", System.Text.Encoding.ASCII.GetBytes(terser.Get("/MSH-10")) } } } ); // Audit actor for PDQ retVal.Actors.Add(new AuditActorData() { UserIdentifier = destData, UserIsRequestor = false, ActorRoleCode = new List <CodeValue>() { new CodeValue("110152", "DCM") { DisplayName = "Destination" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Dns.GetHostName(), AlternativeUserId = Process.GetCurrentProcess().Id.ToString() }); break; } case "ITI-8": { retVal = new AuditData(DateTime.Now, action, outcome, EventIdentifierType.PatientRecord, new CodeValue(itiName, "IHE Transactions") { DisplayName = "Patient Identity Feed" }); // Audit actor for Patient Identity Source retVal.Actors.Add(new AuditActorData() { UserIsRequestor = true, UserIdentifier = sourceData, ActorRoleCode = new List <CodeValue>() { new CodeValue("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointId = msgEvent.SolicitorEndpoint.Host, NetworkAccessPointType = msgEvent.SolicitorEndpoint.HostNameType == UriHostNameType.Dns ? NetworkAccessPointType.MachineName : NetworkAccessPointType.IPAddress }); // Audit actor for PDQ retVal.Actors.Add(new AuditActorData() { UserIdentifier = destData, UserIsRequestor = false, ActorRoleCode = new List <CodeValue>() { new CodeValue("110152", "DCM") { DisplayName = "Destination" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Dns.GetHostName(), AlternativeUserId = Process.GetCurrentProcess().Id.ToString() }); break; } case "ITI-9": { retVal = new AuditData(DateTime.Now, action, outcome, EventIdentifierType.Query, new CodeValue(itiName, "IHE Transactions") { DisplayName = "PIX Query" }); // Audit actor for Patient Identity Source retVal.Actors.Add(new AuditActorData() { UserIsRequestor = true, UserIdentifier = sourceData, ActorRoleCode = new List <CodeValue>() { new CodeValue("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointId = msgEvent.SolicitorEndpoint.Host, NetworkAccessPointType = msgEvent.SolicitorEndpoint.HostNameType == UriHostNameType.Dns ? NetworkAccessPointType.MachineName : NetworkAccessPointType.IPAddress }); // Add query parameters retVal.AuditableObjects.Add( new AuditableObject() { IDTypeCode = AuditableObjectIdType.Custom, CustomIdTypeCode = new CodeValue("ITI-9", "IHE Transactions") { DisplayName = "PIX Query" }, QueryData = Convert.ToBase64String(CreateMessageSerialized(msgEvent.Message)), Type = AuditableObjectType.SystemObject, Role = AuditableObjectRole.Query, ObjectId = terser.Get("/QPD-2"), ObjectData = new Dictionary <string, byte[]>() { { "MSH-10", System.Text.Encoding.ASCII.GetBytes(terser.Get("/MSH-10")) } } } ); // Audit actor for PDQ retVal.Actors.Add(new AuditActorData() { UserIdentifier = destData, UserIsRequestor = false, ActorRoleCode = new List <CodeValue>() { new CodeValue("110152", "DCM") { DisplayName = "Destination" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Dns.GetHostName(), AlternativeUserId = Process.GetCurrentProcess().Id.ToString() }); break; } } var expDatOid = config.OidRegistrar.GetOid("CR_CID"); // HACK: Use only patient identifiers in the output foreach (var id in identifiers.Where(o => o.Domain != expDatOid.Oid).ToArray()) { RegistrationEvent evt = this.m_dataPersistence.GetContainer(id, true) as RegistrationEvent; if (evt != null) { identifiers.Remove(id); foreach (Person subj in evt.FindAllComponents(HealthServiceRecordSiteRoleType.SubjectOf)) { identifiers.Add(new VersionedDomainIdentifier() { Identifier = subj.Id.ToString(), Domain = expDatOid.Oid }); } } } // Audit patients foreach (var id in identifiers) { // If the id is not a patient then // Construct the audit object AuditableObject aud = new AuditableObject() { IDTypeCode = AuditableObjectIdType.PatientNumber, Role = AuditableObjectRole.Patient, Type = AuditableObjectType.Person }; // Lifecycle switch (action) { case ActionType.Create: aud.LifecycleType = AuditableObjectLifecycle.Creation; break; case ActionType.Delete: aud.LifecycleType = AuditableObjectLifecycle.LogicalDeletion; break; case ActionType.Execute: aud.LifecycleType = AuditableObjectLifecycle.Access; break; case ActionType.Read: aud.LifecycleType = AuditableObjectLifecycle.Disclosure; break; case ActionType.Update: aud.LifecycleType = AuditableObjectLifecycle.Amendment; break; } aud.ObjectData.Add("MSH-10", System.Text.Encoding.ASCII.GetBytes(terser.Get("/MSH-10"))); aud.ObjectId = String.Format("{1}^^^{2}&{0}&ISO", expDatOid.Oid, id.Identifier, expDatOid.Attributes.Find(o => o.Key == "AssigningAuthorityName").Value); retVal.AuditableObjects.Add(aud); } return(retVal); }
/// <summary> /// Creates the base audit. /// </summary> /// <param name="actionType">Type of the action.</param> /// <param name="eventTypeCode">The event type code.</param> /// <param name="eventIdentifierType">Type of the event identifier.</param> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <returns>Returns the created base audit data.</returns> protected virtual AuditData CreateBaseAudit(ActionType actionType, EventTypeCode eventTypeCode, EventIdentifierType eventIdentifierType, OutcomeIndicator outcomeIndicator) { return(this.CreateBaseAudit(actionType, CreateAuditCode(eventTypeCode), eventIdentifierType, outcomeIndicator)); }
/// <summary> /// Send audit update /// </summary> protected virtual void SendAuditUpdate(OutcomeIndicator outcome, IMessage message, IEnumerable <IdentifiedData> results) { AuditUtil.AuditUpdate(outcome, null, results?.ToArray()); }
/// <summary> /// Audits the generic error. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <param name="eventTypeCode">The event type code.</param> /// <param name="eventIdentifierType">Type of the event identifier.</param> /// <param name="exception">The exception.</param> public abstract void AuditGenericError(OutcomeIndicator outcomeIndicator, EventTypeCode eventTypeCode, EventIdentifierType eventIdentifierType, Exception exception);
/// <summary> /// Create the audit /// </summary> private static AuditMessage CreateAudit(ActionType action, OutcomeIndicator outcome, EventIdentifierType eventId, CodeValue <String> eventType, IMessage message, String remoteEndpoint) { var retVal = new AuditMessage( DateTime.Now, action, outcome, eventId, eventType); Terser mTerser = new Terser(message); retVal.Actors = new List <AuditActorData>() { new AuditActorData() { UserIdentifier = String.Format("{0}|{1}", mTerser.Get("/MSH-3"), mTerser.Get("/MSH-4")), AlternativeUserId = Process.GetCurrentProcess().Id.ToString(), ActorRoleCode = new List <CodeValue <string> >() { new CodeValue <String>("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointTypeSpecified = true, NetworkAccessPointId = Dns.GetHostName() }, new AuditActorData() { UserIdentifier = String.Format("{0}|{1}", mTerser.Get("/MSH-5"), mTerser.Get("/MSH-6")), ActorRoleCode = new List <CodeValue <string> >() { new CodeValue <String>("110152", "DCM") { DisplayName = "Desintation" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointTypeSpecified = true, NetworkAccessPointId = remoteEndpoint } }; // Human? WindowsIdentity identity = WindowsIdentity.GetCurrent(); if (Environment.UserInteractive) { retVal.Actors.Add(new AuditActorData() { UserIdentifier = identity.Name, AlternativeUserId = String.Format("{0}\\{1}", Environment.UserDomainName, Environment.UserName), ActorRoleCode = identity.Groups.Select(o => new CodeValue <String>(o.Translate(typeof(NTAccount)).Value, Environment.UserDomainName)).ToList() }); } // Audit source retVal.SourceIdentification = new List <AuditSourceIdentificationType>() { new AuditSourceIdentificationType() { AuditEnterpriseSiteID = ConfigurationManager.AppSettings["giis_device_id_oid"], AuditSourceID = String.Format("{0}\\{1}", Environment.UserDomainName, Environment.MachineName), AuditSourceTypeCode = new List <CodeValue <AuditSourceType> >() { new CodeValue <AuditSourceType>(AuditSourceType.EndUserInterface) } } }; return(retVal); }
/// <summary> /// Creates the security resource delete audit. /// </summary> /// <param name="securityEntity">The security entity.</param> /// <param name="eventTypeCode">The event type code.</param> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <returns>Returns the created audit.</returns> protected virtual AuditData CreateSecurityResourceDeleteAudit(T securityEntity, AuditCode eventTypeCode, OutcomeIndicator outcomeIndicator) { var audit = this.CreateBaseAudit(ActionType.Delete, eventTypeCode, EventIdentifierType.ApplicationActivity, outcomeIndicator); if (typeof(T) == typeof(SecurityUser)) { audit.AuditableObjects.Add(this.CreateBaseAuditableObject(AuditableObjectIdType.UserIdentifier, AuditableObjectLifecycle.LogicalDeletion, securityEntity.Key.ToString(), AuditableObjectRole.SecurityUser, AuditableObjectType.Person)); } else if (typeof(T) == typeof(SecurityRole)) { audit.AuditableObjects.Add(this.CreateBaseAuditableObject(AuditableObjectIdType.UserIdentifier, AuditableObjectLifecycle.LogicalDeletion, securityEntity.Key.ToString(), AuditableObjectRole.SecurityGroup, AuditableObjectType.Other)); } else { audit.AuditableObjects.Add(this.CreateBaseAuditableObject(AuditableObjectIdType.UserIdentifier, AuditableObjectLifecycle.LogicalDeletion, securityEntity.Key.ToString(), AuditableObjectRole.SecurityResource, AuditableObjectType.Other)); } return(audit); }
/// <summary> /// Audits the application stop. /// </summary> /// <param name="outcomeIndicator">The outcome indicator.</param> public void AuditApplicationStop(OutcomeIndicator outcomeIndicator) { var audit = this.CreateBaseAudit(ActionType.Execute, EventTypeCode.ApplicationStart, EventIdentifierType.ApplicationActivity, outcomeIndicator); AuditService.SendAudit(audit); }
/// <summary> /// Audit data action on FHIR interface /// </summary> private void AuditDataAction(TypeRestfulInteraction type, OutcomeIndicator outcome, params Resource[] objects) { AuditData audit = new AuditData(DateTime.Now, ActionType.Execute, outcome, EventIdentifierType.ApplicationActivity, new AuditCode(Hl7.Fhir.Utility.EnumUtility.GetLiteral(type), "http://hl7.org/fhir/ValueSet/type-restful-interaction")); AuditableObjectLifecycle lifecycle = AuditableObjectLifecycle.NotSet; switch (type) { case TypeRestfulInteraction.Create: audit.ActionCode = ActionType.Create; audit.EventIdentifier = EventIdentifierType.Import; lifecycle = AuditableObjectLifecycle.Creation; break; case TypeRestfulInteraction.Delete: audit.ActionCode = ActionType.Delete; audit.EventIdentifier = EventIdentifierType.Import; lifecycle = AuditableObjectLifecycle.LogicalDeletion; break; case TypeRestfulInteraction.HistoryInstance: case TypeRestfulInteraction.HistoryType: case TypeRestfulInteraction.SearchType: audit.ActionCode = ActionType.Execute; audit.EventIdentifier = EventIdentifierType.Query; lifecycle = AuditableObjectLifecycle.Disclosure; audit.AuditableObjects.Add(new AuditableObject() { QueryData = RestOperationContext.Current?.IncomingRequest.Url.ToString(), Role = AuditableObjectRole.Query, Type = AuditableObjectType.SystemObject, ObjectData = RestOperationContext.Current?.IncomingRequest.Headers.AllKeys.Where(o => o.Equals("accept", StringComparison.OrdinalIgnoreCase)).Select(o => new ObjectDataExtension(o, RestOperationContext.Current.IncomingRequest.Headers.Get(o))).ToList() }); break; case TypeRestfulInteraction.Update: case TypeRestfulInteraction.Patch: audit.ActionCode = ActionType.Update; audit.EventIdentifier = EventIdentifierType.Import; lifecycle = AuditableObjectLifecycle.Amendment; break; case TypeRestfulInteraction.Vread: case TypeRestfulInteraction.Read: audit.ActionCode = ActionType.Read; audit.EventIdentifier = EventIdentifierType.Query; lifecycle = AuditableObjectLifecycle.Disclosure; audit.AuditableObjects.Add(new AuditableObject() { QueryData = RestOperationContext.Current?.IncomingRequest.Url.ToString(), Role = AuditableObjectRole.Query, Type = AuditableObjectType.SystemObject, ObjectData = RestOperationContext.Current?.IncomingRequest.Headers.AllKeys.Where(o => o.Equals("accept", StringComparison.OrdinalIgnoreCase)).Select(o => new ObjectDataExtension(o, RestOperationContext.Current.IncomingRequest.Headers.Get(o))).ToList() }); break; } AuditUtil.AddLocalDeviceActor(audit); AuditUtil.AddUserActor(audit); audit.AuditableObjects.AddRange(objects.SelectMany(o => this.CreateAuditObjects(o, lifecycle))); AuditUtil.SendAudit(audit); }
/// <summary> /// Autility utility which can be used to send a data audit /// </summary> public static void AuditDataAction <TData>(EventTypeCodes typeCode, ActionType action, AuditableObjectLifecycle lifecycle, EventIdentifierType eventType, OutcomeIndicator outcome, String queryPerformed, params TData[] data) where TData : IdentifiedData { traceSource.TraceVerbose("Create AuditDataAction audit"); AuditCode eventTypeId = CreateAuditActionCode(typeCode); AuditData audit = new AuditData(DateTime.Now, action, outcome, eventType, eventTypeId); AddDeviceActor(audit); AddUserActor(audit); AddSenderDeviceActor(audit); // Objects //audit.AuditableObjects = data.Select(o => //{ // var idTypeCode = AuditableObjectIdType.Custom; // var roleCode = AuditableObjectRole.Resource; // var objType = AuditableObjectType.Other; // if (o is Patient) // { // idTypeCode = AuditableObjectIdType.PatientNumber; // roleCode = AuditableObjectRole.Patient; // objType = AuditableObjectType.Person; // } // else if (o is UserEntity || o is Provider) // { // idTypeCode = AuditableObjectIdType.UserIdentifier; // objType = AuditableObjectType.Person; // roleCode = AuditableObjectRole.Provider; // } // else if (o is Entity) // idTypeCode = AuditableObjectIdType.EnrolleeNumber; // else if (o is Act) // { // idTypeCode = AuditableObjectIdType.EncounterNumber; // roleCode = AuditableObjectRole.Report; // } // else if (o is SecurityUser) // { // idTypeCode = AuditableObjectIdType.UserIdentifier; // roleCode = AuditableObjectRole.SecurityUser; // objType = AuditableObjectType.SystemObject; // } // return new AuditableObject() // { // IDTypeCode = idTypeCode, // CustomIdTypeCode = idTypeCode == AuditableObjectIdType.Custom ? new AuditCode(o.GetType().Name, "OpenIZTable") : null, // LifecycleType = lifecycle, // ObjectId = o.Key?.ToString(), // Role = roleCode, // Type = objType // }; //}).ToList(); // Query performed if (!String.IsNullOrEmpty(queryPerformed)) { audit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.SearchCritereon, LifecycleType = AuditableObjectLifecycle.Access, QueryData = queryPerformed, Role = AuditableObjectRole.Query, Type = AuditableObjectType.SystemObject }); } SendAudit(audit); }
/// <summary> /// Creates the security resource query audit. /// </summary> /// <param name="eventTypeCode">The event type code.</param> /// <param name="outcomeIndicator">The outcome indicator.</param> /// <returns>Returns the created audit.</returns> protected virtual AuditData CreateSecurityResourceQueryAudit(AuditCode eventTypeCode, OutcomeIndicator outcomeIndicator) { return(this.CreateBaseAudit(ActionType.Read, eventTypeCode, EventIdentifierType.ApplicationActivity, outcomeIndicator)); }