From 4ec01b0ef079a4be0d99198b2d620d94e04dc6f3 Mon Sep 17 00:00:00 2001 From: Ike <137194738+ike-kottlowski@users.noreply.github.com> Date: Tue, 15 Aug 2023 14:16:02 -0700 Subject: [PATCH] PM-2427-Defect-Cannot-delete-account-if-User-has-auth-request-on-table-FK-constraint (#3118) * updated migrations and ef repo * removed route alias --------- Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> --- src/Identity/Controllers/SsoController.cs | 2 - .../Repositories/UserRepository.cs | 1 + .../dbo/Stored Procedures/User_DeleteById.sql | 17 ++- .../2023-07-17_00_DeleteUserSproc.sql | 136 ++++++++++++++++++ 4 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 util/Migrator/DbScripts/2023-07-17_00_DeleteUserSproc.sql diff --git a/src/Identity/Controllers/SsoController.cs b/src/Identity/Controllers/SsoController.cs index f3a9afb17c..58a2682914 100644 --- a/src/Identity/Controllers/SsoController.cs +++ b/src/Identity/Controllers/SsoController.cs @@ -14,8 +14,6 @@ using Microsoft.AspNetCore.Mvc; namespace Bit.Identity.Controllers; -// TODO: 2022-01-12, Remove account alias -[Route("account/[action]")] [Route("sso/[action]")] public class SsoController : Controller { diff --git a/src/Infrastructure.EntityFramework/Repositories/UserRepository.cs b/src/Infrastructure.EntityFramework/Repositories/UserRepository.cs index c48b8a582b..ba422c789b 100644 --- a/src/Infrastructure.EntityFramework/Repositories/UserRepository.cs +++ b/src/Infrastructure.EntityFramework/Repositories/UserRepository.cs @@ -155,6 +155,7 @@ public class UserRepository : Repository, IUserR dbContext.Ciphers.RemoveRange(dbContext.Ciphers.Where(c => c.UserId == user.Id)); dbContext.Folders.RemoveRange(dbContext.Folders.Where(f => f.UserId == user.Id)); + dbContext.AuthRequests.RemoveRange(dbContext.AuthRequests.Where(s => s.UserId == user.Id)); dbContext.Devices.RemoveRange(dbContext.Devices.Where(d => d.UserId == user.Id)); var collectionUsers = from cu in dbContext.CollectionUsers join ou in dbContext.OrganizationUsers on cu.OrganizationUserId equals ou.Id diff --git a/src/Sql/dbo/Stored Procedures/User_DeleteById.sql b/src/Sql/dbo/Stored Procedures/User_DeleteById.sql index ce32f2f24a..1f16c15aaa 100644 --- a/src/Sql/dbo/Stored Procedures/User_DeleteById.sql +++ b/src/Sql/dbo/Stored Procedures/User_DeleteById.sql @@ -31,6 +31,13 @@ BEGIN WHERE [UserId] = @Id + -- Delete AuthRequest, must be before Device + DELETE + FROM + [dbo].[AuthRequest] + WHERE + [UserId] = @Id + -- Delete devices DELETE FROM @@ -43,7 +50,7 @@ BEGIN CU FROM [dbo].[CollectionUser] CU - INNER JOIN + INNER JOIN [dbo].[OrganizationUser] OU ON OU.[Id] = CU.[OrganizationUserId] WHERE OU.[UserId] = @Id @@ -53,7 +60,7 @@ BEGIN GU FROM [dbo].[GroupUser] GU - INNER JOIN + INNER JOIN [dbo].[OrganizationUser] OU ON OU.[Id] = GU.[OrganizationUserId] WHERE OU.[UserId] = @Id @@ -63,7 +70,7 @@ BEGIN AP FROM [dbo].[AccessPolicy] AP - INNER JOIN + INNER JOIN [dbo].[OrganizationUser] OU ON OU.[Id] = AP.[OrganizationUserId] WHERE [UserId] = @Id @@ -95,7 +102,7 @@ BEGIN [dbo].[EmergencyAccess] WHERE [GrantorId] = @Id - OR + OR [GranteeId] = @Id -- Delete Sends @@ -104,7 +111,7 @@ BEGIN [dbo].[Send] WHERE [UserId] = @Id - + -- Finally, delete the user DELETE FROM diff --git a/util/Migrator/DbScripts/2023-07-17_00_DeleteUserSproc.sql b/util/Migrator/DbScripts/2023-07-17_00_DeleteUserSproc.sql new file mode 100644 index 0000000000..cbfb972901 --- /dev/null +++ b/util/Migrator/DbScripts/2023-07-17_00_DeleteUserSproc.sql @@ -0,0 +1,136 @@ +IF OBJECT_ID('[dbo].[User_DeleteById]') IS NOT NULL + BEGIN + DROP PROCEDURE [dbo].[User_DeleteById] +END +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO + +CREATE PROCEDURE [dbo].[User_DeleteById] + @Id UNIQUEIDENTIFIER +WITH + RECOMPILE +AS +BEGIN + SET NOCOUNT ON + DECLARE @BatchSize INT = 100 + + -- Delete ciphers + WHILE @BatchSize > 0 + BEGIN + BEGIN TRANSACTION User_DeleteById_Ciphers + + DELETE TOP(@BatchSize) + FROM + [dbo].[Cipher] + WHERE + [UserId] = @Id + + SET @BatchSize = @@ROWCOUNT + + COMMIT TRANSACTION User_DeleteById_Ciphers + END + + BEGIN TRANSACTION User_DeleteById + + -- Delete folders + DELETE + FROM + [dbo].[Folder] + WHERE + [UserId] = @Id + + -- Delete AuthRequest, must be before Device + DELETE + FROM + [dbo].[AuthRequest] + WHERE + [UserId] = @Id + + -- Delete devices + DELETE + FROM + [dbo].[Device] + WHERE + [UserId] = @Id + + -- Delete collection users + DELETE + CU + FROM + [dbo].[CollectionUser] CU + INNER JOIN + [dbo].[OrganizationUser] OU ON OU.[Id] = CU.[OrganizationUserId] + WHERE + OU.[UserId] = @Id + + -- Delete group users + DELETE + GU + FROM + [dbo].[GroupUser] GU + INNER JOIN + [dbo].[OrganizationUser] OU ON OU.[Id] = GU.[OrganizationUserId] + WHERE + OU.[UserId] = @Id + + -- Delete AccessPolicy + DELETE + AP + FROM + [dbo].[AccessPolicy] AP + INNER JOIN + [dbo].[OrganizationUser] OU ON OU.[Id] = AP.[OrganizationUserId] + WHERE + [UserId] = @Id + + -- Delete organization users + DELETE + FROM + [dbo].[OrganizationUser] + WHERE + [UserId] = @Id + + -- Delete provider users + DELETE + FROM + [dbo].[ProviderUser] + WHERE + [UserId] = @Id + + -- Delete SSO Users + DELETE + FROM + [dbo].[SsoUser] + WHERE + [UserId] = @Id + + -- Delete Emergency Accesses + DELETE + FROM + [dbo].[EmergencyAccess] + WHERE + [GrantorId] = @Id + OR + [GranteeId] = @Id + + -- Delete Sends + DELETE + FROM + [dbo].[Send] + WHERE + [UserId] = @Id + + -- Finally, delete the user + DELETE + FROM + [dbo].[User] + WHERE + [Id] = @Id + + COMMIT TRANSACTION User_DeleteById +END +