From 2f225bfbedfdd3e519973115733b7ce68996c5bc Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Fri, 23 Jan 2026 08:59:51 -0500 Subject: [PATCH] feat: add DeleteMany procedure for EmergencyAccess --- .../IEmergencyAccessRepository.cs | 7 ++++++ .../Repositories/EmergencyAccessRepository.cs | 12 +++++++-- .../Repositories/EmergencyAccessRepository.cs | 15 +++++++++++ .../EmergencyAccess_DeleteManyById.sql | 25 +++++++++++++++++++ ...-01-23_00_AddDeleteManyEmergencyAccess.sql | 25 +++++++++++++++++++ 5 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 src/Sql/dbo/Auth/Stored Procedures/EmergencyAccess_DeleteManyById.sql create mode 100644 util/Migrator/DbScripts/2026-01-23_00_AddDeleteManyEmergencyAccess.sql diff --git a/src/Core/Auth/Repositories/IEmergencyAccessRepository.cs b/src/Core/Auth/Repositories/IEmergencyAccessRepository.cs index 5f11281b36..5b4ad47180 100644 --- a/src/Core/Auth/Repositories/IEmergencyAccessRepository.cs +++ b/src/Core/Auth/Repositories/IEmergencyAccessRepository.cs @@ -30,4 +30,11 @@ public interface IEmergencyAccessRepository : IRepository /// A list of emergency access with updated keys UpdateEncryptedDataForKeyRotation UpdateForKeyRotation(Guid grantorId, IEnumerable emergencyAccessKeys); + + /// + /// Deletes multiple emergency access records by their IDs + /// + /// Ids of records to be deleted + /// void + Task DeleteManyAsync(ICollection emergencyAccessIds); } diff --git a/src/Infrastructure.Dapper/Auth/Repositories/EmergencyAccessRepository.cs b/src/Infrastructure.Dapper/Auth/Repositories/EmergencyAccessRepository.cs index 4d597ab045..890cfc4e50 100644 --- a/src/Infrastructure.Dapper/Auth/Repositories/EmergencyAccessRepository.cs +++ b/src/Infrastructure.Dapper/Auth/Repositories/EmergencyAccessRepository.cs @@ -9,8 +9,6 @@ using Bit.Infrastructure.Dapper.Repositories; using Dapper; using Microsoft.Data.SqlClient; -#nullable enable - namespace Bit.Infrastructure.Dapper.Auth.Repositories; public class EmergencyAccessRepository : Repository, IEmergencyAccessRepository @@ -152,4 +150,14 @@ public class EmergencyAccessRepository : Repository, IEme } }; } + + /// + public async Task DeleteManyAsync(ICollection emergencyAccessIds) + { + using var connection = new SqlConnection(ConnectionString); + await connection.ExecuteAsync( + "[dbo].[EmergencyAccess_DeleteMany]", + new { EmergencyAccessIds = emergencyAccessIds }, + commandType: CommandType.StoredProcedure); + } } diff --git a/src/Infrastructure.EntityFramework/Auth/Repositories/EmergencyAccessRepository.cs b/src/Infrastructure.EntityFramework/Auth/Repositories/EmergencyAccessRepository.cs index 972a79f0d3..ac6ebbe04c 100644 --- a/src/Infrastructure.EntityFramework/Auth/Repositories/EmergencyAccessRepository.cs +++ b/src/Infrastructure.EntityFramework/Auth/Repositories/EmergencyAccessRepository.cs @@ -144,4 +144,19 @@ public class EmergencyAccessRepository : Repository + public async Task DeleteManyAsync(ICollection emergencyAccessIds) + { + using (var scope = ServiceScopeFactory.CreateScope()) + { + var dbContext = GetDatabaseContext(scope); + var rangeToRemove = from ea in dbContext.EmergencyAccesses + where emergencyAccessIds.Contains(ea.Id) + select ea; + dbContext.EmergencyAccesses.RemoveRange(rangeToRemove); + + await dbContext.SaveChangesAsync(); + } + } + } diff --git a/src/Sql/dbo/Auth/Stored Procedures/EmergencyAccess_DeleteManyById.sql b/src/Sql/dbo/Auth/Stored Procedures/EmergencyAccess_DeleteManyById.sql new file mode 100644 index 0000000000..176a2dd3b7 --- /dev/null +++ b/src/Sql/dbo/Auth/Stored Procedures/EmergencyAccess_DeleteManyById.sql @@ -0,0 +1,25 @@ +CREATE PROCEDURE [dbo].[EmergencyAccess_DeleteManyById] + @EmergencyAccessIds [dbo].[GuidIdArray] READONLY +AS +BEGIN + SET NOCOUNT ON + + DECLARE @BatchSize INT = 100 + + -- Delete EmergencyAccess Records + WHILE @BatchSize > 0 + BEGIN + BEGIN TRANSACTION + + DELETE TOP(@BatchSize) EA + FROM + [dbo].[EmergencyAccess] EA + INNER JOIN + @EmergencyAccessIds EAI ON EAI.Id = EA.Id + + SET @BatchSize = @@ROWCOUNT + + COMMIT TRANSACTION + END +END +GO \ No newline at end of file diff --git a/util/Migrator/DbScripts/2026-01-23_00_AddDeleteManyEmergencyAccess.sql b/util/Migrator/DbScripts/2026-01-23_00_AddDeleteManyEmergencyAccess.sql new file mode 100644 index 0000000000..eff5a615c4 --- /dev/null +++ b/util/Migrator/DbScripts/2026-01-23_00_AddDeleteManyEmergencyAccess.sql @@ -0,0 +1,25 @@ +CREATE OR ALTER PROCEDURE [dbo].[EmergencyAccess_DeleteManyById] + @EmergencyAccessIds [dbo].[GuidIdArray] READONLY +AS +BEGIN + SET NOCOUNT ON + + DECLARE @BatchSize INT = 100 + + -- Delete EmergencyAccess Records + WHILE @BatchSize > 0 + BEGIN + BEGIN TRANSACTION + + DELETE TOP(@BatchSize) EA + FROM + [dbo].[EmergencyAccess] EA + INNER JOIN + @EmergencyAccessIds EAI ON EAI.Id = EA.Id + + SET @BatchSize = @@ROWCOUNT + + COMMIT TRANSACTION + END +END +GO \ No newline at end of file