1
0
mirror of https://github.com/bitwarden/server.git synced 2024-12-24 17:17:40 +01:00

PM-10560: Adding Cascades back to Notification Center (#4769)

* PM-10560: Adding Cascades back

* PM-10560: Add missing Notification FK with CASCADE

* PM-10560: Delete Notification cascades fix

* PM-10560: Further cascades removal, simplifications

* PM-10560: Cleanup

* PM-10560: Cleanup

* PM-10560: Sql migrations fix

* PM-10560: EF revert
This commit is contained in:
Maciej Zieniuk 2024-09-20 14:20:15 +02:00 committed by GitHub
parent 9dedaa5acf
commit 8a515a3f2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 363 additions and 0 deletions

View File

@ -199,6 +199,11 @@ public class OrganizationRepository : Repository<Core.AdminConsole.Entities.Orga
await dbContext.ServiceAccount.Where(sa => sa.OrganizationId == organization.Id)
.ExecuteDeleteAsync();
await dbContext.NotificationStatuses.Where(ns => ns.Notification.OrganizationId == organization.Id)
.ExecuteDeleteAsync();
await dbContext.Notifications.Where(n => n.OrganizationId == organization.Id)
.ExecuteDeleteAsync();
// The below section are 3 SPROCS in SQL Server but are only called by here
await dbContext.OrganizationApiKeys.Where(oa => oa.OrganizationId == organization.Id)
.ExecuteDeleteAsync();

View File

@ -255,6 +255,8 @@ public class UserRepository : Repository<Core.Entities.User, User, Guid>, IUserR
dbContext.EmergencyAccesses.RemoveRange(
dbContext.EmergencyAccesses.Where(ea => ea.GrantorId == user.Id || ea.GranteeId == user.Id));
dbContext.Sends.RemoveRange(dbContext.Sends.Where(s => s.UserId == user.Id));
dbContext.NotificationStatuses.RemoveRange(dbContext.NotificationStatuses.Where(ns => ns.UserId == user.Id));
dbContext.Notifications.RemoveRange(dbContext.Notifications.Where(n => n.UserId == user.Id));
var mappedUser = Mapper.Map<User>(user);
dbContext.Users.Remove(mappedUser);

View File

@ -5,5 +5,11 @@ CREATE TABLE [dbo].[NotificationStatus]
[ReadDate] DATETIME2 (7) NULL,
[DeletedDate] DATETIME2 (7) NULL,
CONSTRAINT [PK_NotificationStatus] PRIMARY KEY CLUSTERED ([NotificationId] ASC, [UserId] ASC),
CONSTRAINT [FK_NotificationStatus_Notification] FOREIGN KEY ([NotificationId]) REFERENCES [dbo].[Notification] ([Id]),
CONSTRAINT [FK_NotificationStatus_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id])
);
GO
CREATE NONCLUSTERED INDEX [IX_NotificationStatus_UserId]
ON [dbo].[NotificationStatus]([UserId] ASC);

View File

@ -119,6 +119,23 @@ BEGIN
WHERE
[OrganizationId] = @Id
-- Delete Notification Status
DELETE
NS
FROM
[dbo].[NotificationStatus] NS
INNER JOIN
[dbo].[Notification] N ON N.[Id] = NS.[NotificationId]
WHERE
N.[OrganizationId] = @Id
-- Delete Notification
DELETE
FROM
[dbo].[Notification]
WHERE
[OrganizationId] = @Id
DELETE
FROM
[dbo].[Organization]

View File

@ -119,6 +119,20 @@ BEGIN
WHERE
[UserId] = @Id
-- Delete Notification Status
DELETE
FROM
[dbo].[NotificationStatus]
WHERE
[UserId] = @Id
-- Delete Notification
DELETE
FROM
[dbo].[Notification]
WHERE
[UserId] = @Id
-- Finally, delete the user
DELETE
FROM

View File

@ -0,0 +1,319 @@
-- NotificationStatus
IF OBJECT_ID('[dbo].[FK_NotificationStatus_Notification]', 'F') IS NOT NULL
BEGIN
ALTER TABLE [dbo].[NotificationStatus]
DROP CONSTRAINT [FK_NotificationStatus_Notification]
END
GO
ALTER TABLE [dbo].[NotificationStatus]
ADD CONSTRAINT [FK_NotificationStatus_Notification] FOREIGN KEY ([NotificationId]) REFERENCES [dbo].[Notification] ([Id])
GO
IF NOT EXISTS(SELECT name
FROM sys.indexes
WHERE name = 'IX_NotificationStatus_UserId')
BEGIN
CREATE NONCLUSTERED INDEX [IX_NotificationStatus_UserId]
ON [dbo].[NotificationStatus] ([UserId] ASC);
END
GO
-- Stored Procedure Organization_DeleteById
CREATE OR ALTER PROCEDURE [dbo].[Organization_DeleteById]
@Id UNIQUEIDENTIFIER
WITH RECOMPILE
AS
BEGIN
SET NOCOUNT ON
EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @Id
DECLARE @BatchSize INT = 100
WHILE @BatchSize > 0
BEGIN
BEGIN TRANSACTION Organization_DeleteById_Ciphers
DELETE TOP(@BatchSize)
FROM
[dbo].[Cipher]
WHERE
[UserId] IS NULL
AND [OrganizationId] = @Id
SET @BatchSize = @@ROWCOUNT
COMMIT TRANSACTION Organization_DeleteById_Ciphers
END
BEGIN TRANSACTION Organization_DeleteById
DELETE
FROM
[dbo].[AuthRequest]
WHERE
[OrganizationId] = @Id
DELETE
FROM
[dbo].[SsoUser]
WHERE
[OrganizationId] = @Id
DELETE
FROM
[dbo].[SsoConfig]
WHERE
[OrganizationId] = @Id
DELETE CU
FROM
[dbo].[CollectionUser] CU
INNER JOIN
[dbo].[OrganizationUser] OU ON [CU].[OrganizationUserId] = [OU].[Id]
WHERE
[OU].[OrganizationId] = @Id
DELETE AP
FROM
[dbo].[AccessPolicy] AP
INNER JOIN
[dbo].[OrganizationUser] OU ON [AP].[OrganizationUserId] = [OU].[Id]
WHERE
[OU].[OrganizationId] = @Id
DELETE GU
FROM
[dbo].[GroupUser] GU
INNER JOIN
[dbo].[OrganizationUser] OU ON [GU].[OrganizationUserId] = [OU].[Id]
WHERE
[OU].[OrganizationId] = @Id
DELETE
FROM
[dbo].[OrganizationUser]
WHERE
[OrganizationId] = @Id
DELETE
FROM
[dbo].[ProviderOrganization]
WHERE
[OrganizationId] = @Id
EXEC [dbo].[OrganizationApiKey_OrganizationDeleted] @Id
EXEC [dbo].[OrganizationConnection_OrganizationDeleted] @Id
EXEC [dbo].[OrganizationSponsorship_OrganizationDeleted] @Id
EXEC [dbo].[OrganizationDomain_OrganizationDeleted] @Id
DELETE
FROM
[dbo].[Project]
WHERE
[OrganizationId] = @Id
DELETE
FROM
[dbo].[Secret]
WHERE
[OrganizationId] = @Id
DELETE AK
FROM
[dbo].[ApiKey] AK
INNER JOIN
[dbo].[ServiceAccount] SA ON [AK].[ServiceAccountId] = [SA].[Id]
WHERE
[SA].[OrganizationId] = @Id
DELETE AP
FROM
[dbo].[AccessPolicy] AP
INNER JOIN
[dbo].[ServiceAccount] SA ON [AP].[GrantedServiceAccountId] = [SA].[Id]
WHERE
[SA].[OrganizationId] = @Id
DELETE
FROM
[dbo].[ServiceAccount]
WHERE
[OrganizationId] = @Id
-- Delete Notification Status
DELETE
NS
FROM
[dbo].[NotificationStatus] NS
INNER JOIN
[dbo].[Notification] N ON N.[Id] = NS.[NotificationId]
WHERE
N.[OrganizationId] = @Id
-- Delete Notification
DELETE
FROM
[dbo].[Notification]
WHERE
[OrganizationId] = @Id
DELETE
FROM
[dbo].[Organization]
WHERE
[Id] = @Id
COMMIT TRANSACTION Organization_DeleteById
END
GO
-- Stored Procedure User_DeleteById
CREATE OR ALTER 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 WebAuthnCredentials
DELETE
FROM
[dbo].[WebAuthnCredential]
WHERE
[UserId] = @Id
-- 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
-- Delete Notification Status
DELETE
FROM
[dbo].[NotificationStatus]
WHERE
[UserId] = @Id
-- Delete Notification
DELETE
FROM
[dbo].[Notification]
WHERE
[UserId] = @Id
-- Finally, delete the user
DELETE
FROM
[dbo].[User]
WHERE
[Id] = @Id
COMMIT TRANSACTION User_DeleteById
END
GO