// FIXME: Update this file to be null safe and then delete the line below #nullable disable using System.Data; using Bit.Core.Dirt.Entities; using Bit.Core.Dirt.Models.Data; using Bit.Core.Dirt.Reports.Models.Data; using Bit.Core.Dirt.Repositories; using Bit.Core.Settings; using Bit.Infrastructure.Dapper.Repositories; using Dapper; using Microsoft.Data.SqlClient; namespace Bit.Infrastructure.Dapper.Dirt; public class OrganizationReportRepository : Repository, IOrganizationReportRepository { public OrganizationReportRepository(GlobalSettings globalSettings) : this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString) { } public OrganizationReportRepository(string connectionString, string readOnlyConnectionString) : base(connectionString, readOnlyConnectionString) { } public async Task GetLatestByOrganizationIdAsync(Guid organizationId) { using (var connection = new SqlConnection(ReadOnlyConnectionString)) { var result = await connection.QuerySingleOrDefaultAsync( $"[{Schema}].[OrganizationReport_GetLatestByOrganizationId]", new { OrganizationId = organizationId }, commandType: CommandType.StoredProcedure); return result; } } public async Task UpdateSummaryDataAsync(Guid organizationId, Guid reportId, string summaryData) { using (var connection = new SqlConnection(ConnectionString)) { var parameters = new { Id = reportId, OrganizationId = organizationId, SummaryData = summaryData, RevisionDate = DateTime.UtcNow }; await connection.ExecuteAsync( $"[{Schema}].[OrganizationReport_UpdateSummaryData]", parameters, commandType: CommandType.StoredProcedure); // Return the updated report return await connection.QuerySingleOrDefaultAsync( $"[{Schema}].[OrganizationReport_ReadById]", new { Id = reportId }, commandType: CommandType.StoredProcedure); } } public async Task GetSummaryDataAsync(Guid reportId) { using (var connection = new SqlConnection(ReadOnlyConnectionString)) { var result = await connection.QuerySingleOrDefaultAsync( $"[{Schema}].[OrganizationReport_GetSummaryDataById]", new { Id = reportId }, commandType: CommandType.StoredProcedure); return result; } } public async Task> GetSummaryDataByDateRangeAsync( Guid organizationId, DateTime startDate, DateTime endDate) { using (var connection = new SqlConnection(ReadOnlyConnectionString)) { var parameters = new { OrganizationId = organizationId, StartDate = startDate, EndDate = endDate }; var results = await connection.QueryAsync( $"[{Schema}].[OrganizationReport_GetSummariesByDateRange]", parameters, commandType: CommandType.StoredProcedure); return results; } } public async Task GetReportDataAsync(Guid reportId) { using (var connection = new SqlConnection(ReadOnlyConnectionString)) { var result = await connection.QuerySingleOrDefaultAsync( $"[{Schema}].[OrganizationReport_GetReportDataById]", new { Id = reportId }, commandType: CommandType.StoredProcedure); return result; } } public async Task UpdateReportDataAsync(Guid organizationId, Guid reportId, string reportData) { using (var connection = new SqlConnection(ConnectionString)) { var parameters = new { OrganizationId = organizationId, Id = reportId, ReportData = reportData, RevisionDate = DateTime.UtcNow }; await connection.ExecuteAsync( $"[{Schema}].[OrganizationReport_UpdateReportData]", parameters, commandType: CommandType.StoredProcedure); // Return the updated report return await connection.QuerySingleOrDefaultAsync( $"[{Schema}].[OrganizationReport_ReadById]", new { Id = reportId }, commandType: CommandType.StoredProcedure); } } public async Task GetApplicationDataAsync(Guid reportId) { using (var connection = new SqlConnection(ReadOnlyConnectionString)) { var result = await connection.QuerySingleOrDefaultAsync( $"[{Schema}].[OrganizationReport_GetApplicationDataById]", new { Id = reportId }, commandType: CommandType.StoredProcedure); return result; } } public async Task UpdateApplicationDataAsync(Guid organizationId, Guid reportId, string applicationData) { using (var connection = new SqlConnection(ConnectionString)) { var parameters = new { OrganizationId = organizationId, Id = reportId, ApplicationData = applicationData, RevisionDate = DateTime.UtcNow }; await connection.ExecuteAsync( $"[{Schema}].[OrganizationReport_UpdateApplicationData]", parameters, commandType: CommandType.StoredProcedure); // Return the updated report return await connection.QuerySingleOrDefaultAsync( $"[{Schema}].[OrganizationReport_ReadById]", new { Id = reportId }, commandType: CommandType.StoredProcedure); } } public async Task UpdateMetricsAsync(Guid reportId, OrganizationReportMetricsData metrics) { using var connection = new SqlConnection(ConnectionString); var parameters = new { Id = reportId, ApplicationCount = metrics.ApplicationCount, ApplicationAtRiskCount = metrics.ApplicationAtRiskCount, CriticalApplicationCount = metrics.CriticalApplicationCount, CriticalApplicationAtRiskCount = metrics.CriticalApplicationAtRiskCount, MemberCount = metrics.MemberCount, MemberAtRiskCount = metrics.MemberAtRiskCount, CriticalMemberCount = metrics.CriticalMemberCount, CriticalMemberAtRiskCount = metrics.CriticalMemberAtRiskCount, PasswordCount = metrics.PasswordCount, PasswordAtRiskCount = metrics.PasswordAtRiskCount, CriticalPasswordCount = metrics.CriticalPasswordCount, CriticalPasswordAtRiskCount = metrics.CriticalPasswordAtRiskCount, RevisionDate = DateTime.UtcNow }; await connection.ExecuteAsync( $"[{Schema}].[OrganizationReport_UpdateMetrics]", parameters, commandType: CommandType.StoredProcedure); } }