Skip to content

Commit

Permalink
PM-10560: Adding Cascades back to Notification Center (#4769)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
mzieniukbw authored Sep 20, 2024
1 parent 9dedaa5 commit 8a515a3
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ await dbContext.ApiKeys.Where(ak => ak.ServiceAccount.OrganizationId == organiza
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ join ou in dbContext.OrganizationUsers on gu.OrganizationUserId equals ou.Id
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);
Expand Down
6 changes: 6 additions & 0 deletions src/Sql/NotificationCenter/dbo/Tables/NotificationStatus.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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);

17 changes: 17 additions & 0 deletions src/Sql/dbo/Stored Procedures/Organization_DeleteById.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
14 changes: 14 additions & 0 deletions src/Sql/dbo/Stored Procedures/User_DeleteById.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 8a515a3

Please sign in to comment.