diff --git a/DotNet/QueryDispatch/Domain/Managers/PatientDispatchManager.cs b/DotNet/QueryDispatch/Domain/Managers/PatientDispatchManager.cs index f45eea044..accfeff8b 100644 --- a/DotNet/QueryDispatch/Domain/Managers/PatientDispatchManager.cs +++ b/DotNet/QueryDispatch/Domain/Managers/PatientDispatchManager.cs @@ -5,6 +5,7 @@ using LantanaGroup.Link.Shared.Application.Models; using LantanaGroup.Link.Shared.Application.Models.Kafka; using LantanaGroup.Link.Shared.Application.Repositories.Interfaces; +using LantanaGroup.Link.Shared.Application.Services.Security; using Quartz; using QueryDispatch.Application.Settings; @@ -44,7 +45,7 @@ public async Task createPatientDispatch(PatientDispatchEntity patientDis //_datastore.Add(patientDispatch); await _repository.AddAsync(patientDispatch); - _logger.LogInformation($"Created patient dispatch for patient id {patientDispatch.PatientId} in facility {patientDispatch.FacilityId}"); + _logger.LogInformation($"Created patient dispatch for patient id {HtmlInputSanitizer.Sanitize(patientDispatch.PatientId)} in facility {HtmlInputSanitizer.Sanitize(patientDispatch.FacilityId)}"); await ScheduleService.CreateJobAndTrigger(patientDispatch, await _schedulerFactory.GetScheduler()); @@ -60,7 +61,7 @@ public async Task createPatientDispatch(PatientDispatchEntity patientDis Action = AuditEventType.Create, EventDate = DateTime.UtcNow, Resource = typeof(PatientDispatchEntity).Name, - Notes = $"Created patient dispatch for patient id {patientDispatch.PatientId} in facility {patientDispatch.FacilityId}" + Notes = $"Created patient dispatch for patient id {HtmlInputSanitizer.Sanitize(patientDispatch.PatientId)} in facility {HtmlInputSanitizer.Sanitize(patientDispatch.FacilityId)}" }; _producer.Produce(nameof(KafkaTopic.AuditableEventOccurred), new Message @@ -75,8 +76,8 @@ public async Task createPatientDispatch(PatientDispatchEntity patientDis } catch (Exception ex) { - _logger.LogError($"Create patient dispatch exception for patient id {patientDispatch.PatientId} in facility {patientDispatch.FacilityId}.", ex); - throw new ApplicationException($"Failed to create patient dispatch record for patient id {patientDispatch.PatientId} in facility {patientDispatch.FacilityId}."); + _logger.LogError($"Create patient dispatch exception for patient id {HtmlInputSanitizer.Sanitize(patientDispatch.PatientId)} in facility {HtmlInputSanitizer.Sanitize(patientDispatch.FacilityId)}.", ex); + throw new ApplicationException($"Failed to create patient dispatch record for patient id {HtmlInputSanitizer.Sanitize(patientDispatch.PatientId)} in facility {HtmlInputSanitizer.Sanitize(patientDispatch.FacilityId)}."); } } @@ -89,7 +90,7 @@ public async Task deletePatientDispatch(string facilityId, string patientI { await _repository.RemoveAsync(entity); } - _logger.LogInformation($"Deleted Patient Dispatch record for patient id {patientId} in facility {facilityId}"); + _logger.LogInformation($"Deleted Patient Dispatch record for patient id {HtmlInputSanitizer.Sanitize(patientId)} in facility {HtmlInputSanitizer.Sanitize(facilityId)}"); var headers = new Headers @@ -121,7 +122,7 @@ public async Task deletePatientDispatch(string facilityId, string patientI } catch (Exception ex) { - _logger.LogError(ex, "Patient dispatch delete exception for patientId {patientId} in facility {facilityId}", patientId, facilityId); + _logger.LogError(ex, "Patient dispatch delete exception for patientId {patientId} in facility {facilityId}", HtmlInputSanitizer.Sanitize(patientId), HtmlInputSanitizer.Sanitize(facilityId)); return false; } diff --git a/DotNet/QueryDispatch/Domain/Managers/QueryDispatchConfigurationManager.cs b/DotNet/QueryDispatch/Domain/Managers/QueryDispatchConfigurationManager.cs index 7489e64de..5c855b5b0 100644 --- a/DotNet/QueryDispatch/Domain/Managers/QueryDispatchConfigurationManager.cs +++ b/DotNet/QueryDispatch/Domain/Managers/QueryDispatchConfigurationManager.cs @@ -7,6 +7,7 @@ using LantanaGroup.Link.Shared.Application.Models; using LantanaGroup.Link.Shared.Application.Models.Kafka; using LantanaGroup.Link.Shared.Application.Repositories.Interfaces; +using LantanaGroup.Link.Shared.Application.Services.Security; using Quartz; using QueryDispatch.Application.Settings; @@ -63,7 +64,7 @@ public async Task SaveConfigEntity(QueryDispatchConfigurationEntity config, List await _repository.UpdateAsync(config, cancellationToken); - _logger.LogInformation($"Updated query dispatch configuration for facility {config.FacilityId}"); + _logger.LogInformation($"Updated query dispatch configuration for facility {HtmlInputSanitizer.Sanitize(config.FacilityId)}"); @@ -88,8 +89,8 @@ public async Task SaveConfigEntity(QueryDispatchConfigurationEntity config, List } catch (Exception ex) { - _logger.LogError($"Failed to update query dispatch configuration for facility {config.FacilityId}.", ex); - throw new ApplicationException($"Failed to update query dispatch configuration for facility {config.FacilityId}."); + _logger.LogError($"Failed to update query dispatch configuration for facility {HtmlInputSanitizer.Sanitize(config.FacilityId)}.", ex); + throw new ApplicationException($"Failed to update query dispatch configuration for facility {HtmlInputSanitizer.Sanitize(config.FacilityId)}."); } } @@ -101,7 +102,7 @@ public async Task AddConfigEntity(QueryDispatchConfigurationEntity config, Cance { await _repository.AddAsync(config, cancellationToken); - _logger.LogInformation($"Created query dispatch configuration for facility {config.FacilityId}"); + _logger.LogInformation($"Created query dispatch configuration for facility {HtmlInputSanitizer.Sanitize(config.FacilityId)}"); var auditMessage = new AuditEventMessage @@ -125,8 +126,8 @@ public async Task AddConfigEntity(QueryDispatchConfigurationEntity config, Cance } catch (Exception ex) { - _logger.LogError($"Failed to create query dispatch configuration for facility {config.FacilityId}.", ex); - throw new ApplicationException($"Failed to create query dispatch configuration for facility {config.FacilityId}."); + _logger.LogError($"Failed to create query dispatch configuration for facility {HtmlInputSanitizer.Sanitize(config.FacilityId)}.", ex); + throw new ApplicationException($"Failed to create query dispatch configuration for facility {HtmlInputSanitizer.Sanitize(config.FacilityId)}."); } } @@ -147,7 +148,7 @@ public async Task DeleteConfigEntity(string facilityId, CancellationToken cancel } await _repository.DeleteAsync(config.Id, cancellationToken); - _logger.LogInformation($"Deleted query dispatch configuration for facility {facilityId}"); + _logger.LogInformation($"Deleted query dispatch configuration for facility {HtmlInputSanitizer.Sanitize(facilityId)}"); var auditMessage = new AuditEventMessage @@ -174,8 +175,8 @@ public async Task DeleteConfigEntity(string facilityId, CancellationToken cancel } catch (Exception ex) { - _logger.LogError($"Failed to delete query dispatch configuration for facilityId {facilityId}", ex); - throw new ApplicationException($"Failed to delete query dispatch configuration for facilityId {facilityId}"); + _logger.LogError($"Failed to delete query dispatch configuration for facilityId {HtmlInputSanitizer.Sanitize(facilityId)}", ex); + throw new ApplicationException($"Failed to delete query dispatch configuration for facilityId {HtmlInputSanitizer.Sanitize(facilityId)}"); } } diff --git a/DotNet/QueryDispatch/Domain/Managers/ScheduledReportManager.cs b/DotNet/QueryDispatch/Domain/Managers/ScheduledReportManager.cs index c2822f48b..97149b826 100644 --- a/DotNet/QueryDispatch/Domain/Managers/ScheduledReportManager.cs +++ b/DotNet/QueryDispatch/Domain/Managers/ScheduledReportManager.cs @@ -5,6 +5,7 @@ using LantanaGroup.Link.Shared.Application.Models; using LantanaGroup.Link.Shared.Application.Models.Kafka; using LantanaGroup.Link.Shared.Application.Repositories.Interfaces; +using LantanaGroup.Link.Shared.Application.Services.Security; using Quartz; using QueryDispatch.Application.Settings; @@ -46,7 +47,7 @@ public async Task createScheduledReport(ScheduledReportEntity scheduledR await _scheduledReportRepository.AddAsync(scheduledReport); - _logger.LogInformation($"Created schedule report for faciltiy {scheduledReport.FacilityId}"); + _logger.LogInformation($"Created schedule report for faciltiy {HtmlInputSanitizer.Sanitize(scheduledReport.FacilityId)}"); var headers = new Headers { @@ -77,8 +78,8 @@ public async Task createScheduledReport(ScheduledReportEntity scheduledR } catch (Exception ex) { - _logger.LogError($"Failed to create scheduled report for facility {scheduledReport.FacilityId}.", ex); - throw new ApplicationException($"Failed to create scheduled report for facility {scheduledReport.FacilityId}."); + _logger.LogError($"Failed to create scheduled report for facility {HtmlInputSanitizer.Sanitize(scheduledReport.FacilityId)}.", ex); + throw new ApplicationException($"Failed to create scheduled report for facility {HtmlInputSanitizer.Sanitize(scheduledReport.FacilityId)}."); } } @@ -128,7 +129,7 @@ public async Task UpdateScheduledReport(ScheduledReportEntity existingReport, Sc await _scheduledReportRepository.UpdateAsync(existingReport); - _logger.LogInformation($"Update scheduled report type {newReportPeriod.ReportType} for facility id {existingReport.FacilityId}"); + _logger.LogInformation($"Update scheduled report type {HtmlInputSanitizer.Sanitize(newReportPeriod.ReportType)} for facility id {HtmlInputSanitizer.Sanitize(existingReport.FacilityId)}"); var headers = new Headers { @@ -158,8 +159,8 @@ public async Task UpdateScheduledReport(ScheduledReportEntity existingReport, Sc } catch (Exception ex) { - _logger.LogError($"Failed to update scheduled report for facility id {existingReport.FacilityId}.", ex); - throw new ApplicationException($"Failed to update scheduled report for facility id {existingReport.FacilityId}."); + _logger.LogError($"Failed to update scheduled report for facility id {HtmlInputSanitizer.Sanitize(existingReport.FacilityId)}.", ex); + throw new ApplicationException($"Failed to update scheduled report for facility id {HtmlInputSanitizer.Sanitize(existingReport.FacilityId)}."); } } } diff --git a/DotNet/QueryDispatch/Jobs/QueryDispatchJob.cs b/DotNet/QueryDispatch/Jobs/QueryDispatchJob.cs index 84c25b38b..fc1090b7a 100644 --- a/DotNet/QueryDispatch/Jobs/QueryDispatchJob.cs +++ b/DotNet/QueryDispatch/Jobs/QueryDispatchJob.cs @@ -9,6 +9,7 @@ using QueryDispatch.Application.Settings; using LantanaGroup.Link.QueryDispatch.Application.Interfaces; using QueryDispatch.Domain.Managers; +using LantanaGroup.Link.Shared.Application.Services.Security; namespace LanatanGroup.Link.QueryDispatch.Jobs { @@ -79,7 +80,7 @@ public async Task Execute(IJobExecutionContext context) _acquisitionProducer.Flush(); - _logger.LogInformation($"Produced Data Acquisition Requested event for facilityId: {patientDispatchEntity.FacilityId}"); + _logger.LogInformation($"Produced Data Acquisition Requested event for facilityId: {HtmlInputSanitizer.Sanitize(patientDispatchEntity.FacilityId)}"); await patientDispatchMgr.deletePatientDispatch(patientDispatchEntity.FacilityId, patientDispatchEntity.PatientId); diff --git a/DotNet/QueryDispatch/Listeners/PatientEventListener.cs b/DotNet/QueryDispatch/Listeners/PatientEventListener.cs index 1d477cde1..c92da008b 100644 --- a/DotNet/QueryDispatch/Listeners/PatientEventListener.cs +++ b/DotNet/QueryDispatch/Listeners/PatientEventListener.cs @@ -9,6 +9,7 @@ using LantanaGroup.Link.Shared.Application.Models; using LantanaGroup.Link.Shared.Application.Models.Kafka; using LantanaGroup.Link.Shared.Application.Repositories.Interfaces; +using LantanaGroup.Link.Shared.Application.Services.Security; using QueryDispatch.Application.Settings; using QueryDispatch.Domain.Managers; using System.Text; @@ -107,7 +108,7 @@ await _patientEventConsumer.ConsumeWithInstrumentation(async (result, cancellati throw new DeadLetterException("Correlation Id missing"); } - _logger.LogInformation($"Consumed Patient Event for: Facility '{consumeResult.Message.Key}'. PatientId '{value.PatientId}' with a event type of {value.EventType}"); + _logger.LogInformation($"Consumed Patient Event for: Facility '{HtmlInputSanitizer.Sanitize(consumeResult.Message.Key)}'. PatientId '{HtmlInputSanitizer.Sanitize(value.PatientId)}' with a event type of {HtmlInputSanitizer.Sanitize(value.EventType)}"); //ScheduledReportEntity scheduledReport = getScheduledReportQuery.Execute(consumeResult.Message.Key); ScheduledReportEntity scheduledReport = await scheduledReportRepository.FirstOrDefaultAsync(x => x.FacilityId == consumeResult.Message.Key); @@ -125,21 +126,21 @@ await _patientEventConsumer.ConsumeWithInstrumentation(async (result, cancellati if (dispatchSchedule == null) { - throw new TransientException($"Query dispatch configuration missing for facility {consumeResult.Message.Key}"); + throw new TransientException($"Query dispatch configuration missing for facility {HtmlInputSanitizer.Sanitize(consumeResult.Message.Key)}"); } DispatchSchedule dischargeDispatchSchedule = dispatchSchedule.DispatchSchedules.FirstOrDefault(x => x.Event == QueryDispatchConstants.EventType.Discharge); if (dischargeDispatchSchedule == null) { - throw new TransientException($"'Discharge' query dispatch configuration missing for facility {consumeResult.Message.Key}"); + throw new TransientException($"'Discharge' query dispatch configuration missing for facility {HtmlInputSanitizer.Sanitize(consumeResult.Message.Key)}"); } PatientDispatchEntity patientDispatch = _queryDispatchFactory.CreatePatientDispatch(consumeResult.Message.Key, value.PatientId, value.EventType, correlationId, scheduledReport, dischargeDispatchSchedule); if (patientDispatch.ScheduledReportPeriods == null || patientDispatch.ScheduledReportPeriods.Count == 0) { - throw new TransientException($"No active scheduled report periods found for facility {consumeResult.Message.Key}"); + throw new TransientException($"No active scheduled report periods found for facility {HtmlInputSanitizer.Sanitize(consumeResult.Message.Key)}"); } await patientDispatchMgr.createPatientDispatch(patientDispatch); @@ -148,12 +149,12 @@ await _patientEventConsumer.ConsumeWithInstrumentation(async (result, cancellati } catch (DeadLetterException ex) { - _deadLetterExceptionHandler.HandleException(consumeResult, ex, consumeResult.Key); + _deadLetterExceptionHandler.HandleException(consumeResult, ex, HtmlInputSanitizer.Sanitize(consumeResult.Key)); _patientEventConsumer.Commit(consumeResult); } catch (TransientException ex) { - _transientExceptionHandler.HandleException(consumeResult, ex, consumeResult.Key); + _transientExceptionHandler.HandleException(consumeResult, ex, HtmlInputSanitizer.Sanitize(consumeResult.Key)); _patientEventConsumer.Commit(consumeResult); } catch (Exception ex) diff --git a/DotNet/QueryDispatch/Presentation/Controllers/QueryDispatchController.cs b/DotNet/QueryDispatch/Presentation/Controllers/QueryDispatchController.cs index 0a6402e82..a37ca94b4 100644 --- a/DotNet/QueryDispatch/Presentation/Controllers/QueryDispatchController.cs +++ b/DotNet/QueryDispatch/Presentation/Controllers/QueryDispatchController.cs @@ -4,11 +4,13 @@ using LantanaGroup.Link.QueryDispatch.Domain.Entities; using LantanaGroup.Link.Shared.Application.Repositories.Interfaces; using LantanaGroup.Link.Shared.Application.Services; +using LantanaGroup.Link.Shared.Application.Services.Security; using Link.Authorization.Policies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using QueryDispatch.Application.Settings; using QueryDispatch.Domain.Managers; +using System.Text.Json; namespace LantanaGroup.Link.QueryDispatch.Presentation.Controllers { @@ -68,7 +70,7 @@ public async Task> GetFacilityConfiguration(string facility } catch (Exception ex) { - _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.GetItem, "Get QueryDispatch configuration"), ex, "An exception occurred while attempting to retrieve a QueryDispatch configuration for facility {facilityId}", facilityId); + _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.GetItem, "Get QueryDispatch configuration"), ex, "An exception occurred while attempting to retrieve a QueryDispatch configuration for facility {facilityId}", HtmlInputSanitizer.Sanitize(facilityId)); throw; } @@ -97,7 +99,7 @@ public async Task> CreateQueryDispatchConfiguratio if (string.IsNullOrWhiteSpace(model.FacilityId)) { - _logger.LogError($"Facility Id was not provided in the new query dispatch configuration: {model}."); + _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.GenerateItems), "Facility Id was not provided in the new query dispatch configuration: {model}.", HtmlInputSanitizer.Sanitize(JsonSerializer.Serialize(model))); return BadRequest("Facility Id is required in order to create a query dispatch configuration."); } @@ -105,8 +107,8 @@ public async Task> CreateQueryDispatchConfiguratio { if (!IsDurationFormatValid(schedule.Duration)) { - _logger.LogError($"Duration format is invalid: {schedule.Duration}."); - return BadRequest("Duration format is invalid: " + schedule.Duration + ". Please provide a valid duration format."); + _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.GenerateItems), "Duration format is invalid: {schedule.Duration}.", HtmlInputSanitizer.Sanitize(schedule.Duration)); + return BadRequest("Duration format is invalid: " + HtmlInputSanitizer.Sanitize(schedule.Duration) + ". Please provide a valid duration format."); } } @@ -135,7 +137,7 @@ public async Task> CreateQueryDispatchConfiguratio } catch (Exception ex) { - _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.UpdateItem, "Post QueryDispatch configuration"), ex, "An exception occurred while attempting to save a QueryDispatch configuration for facility " + model.FacilityId); + _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.UpdateItem, "Post QueryDispatch configuration"), ex, "An exception occurred while attempting to save a QueryDispatch configuration for facility " + HtmlInputSanitizer.Sanitize(model.FacilityId)); throw; } @@ -167,7 +169,7 @@ public async Task> DeleteQueryDispatchConfiguratio } catch (Exception ex) { - _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.DeleteItem, "Delete QueryDispatch configuration"), ex, "An exception occurred while attempting to delete a QueryDispatch configuration for facility " + facilityId); + _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.DeleteItem, "Delete QueryDispatch configuration"), ex, "An exception occurred while attempting to delete a QueryDispatch configuration for facility " + HtmlInputSanitizer.Sanitize(facilityId)); throw; } @@ -198,7 +200,7 @@ public async Task> UpdateQueryDispatchConfiguratio if (string.IsNullOrWhiteSpace(facilityId)) { - _logger.LogError($"Facility Id was not provided in the update query dispatch configuration: {model}."); + _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.UpdateItem, "Update QueryDispatch configuration"), "Facility Id was not provided in the update query dispatch configuration: {model}.", HtmlInputSanitizer.Sanitize(facilityId)); return BadRequest("Facility Id is required in order to update a query dispatch configuration."); } @@ -206,7 +208,7 @@ public async Task> UpdateQueryDispatchConfiguratio { if (!IsDurationFormatValid(schedule.Duration)) { - _logger.LogError($"Duration format is invalid: {schedule.Duration}."); + _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.UpdateItem, "Update QueryDispatch configuration"), "Duration format is invalid: {schedule.Duration}.", HtmlInputSanitizer.Sanitize(schedule.Duration)); return BadRequest("Duration format is invalid: " + schedule.Duration + ". Please provide a valid duration format."); } } @@ -237,7 +239,7 @@ public async Task> UpdateQueryDispatchConfiguratio } catch (Exception ex) { - _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.UpdateItem, "Put QueryDispatch configuration"), ex, "An exception occurred while attempting to update a QueryDispatch configuration for facility " + facilityId); + _logger.LogError(new EventId(QueryDispatchConstants.LoggingIds.UpdateItem, "Put QueryDispatch configuration"), ex, "An exception occurred while attempting to update a QueryDispatch configuration for facility " + HtmlInputSanitizer.Sanitize(facilityId)); throw; }