1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-05 05:00:19 -05:00

Null out sponsorship values when foreign key deleted (#1733)

This allows us to maintain record of sponsorships up
until they are explicitly removed. Fixes issues where removing
sponsorships from organizations with invalid sponsorships would error
This commit is contained in:
Matt Gibson 2021-11-24 08:26:11 -06:00 committed by GitHub
parent 29d3e1fd2b
commit fa3f1ad0ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 112 additions and 35 deletions

View File

@ -107,10 +107,9 @@ namespace Bit.Core.Repositories.EntityFramework
.Where(os =>
os.SponsoringOrganizationId == organization.Id ||
os.SponsoredOrganizationId == organization.Id);
dbContext.RemoveRange(sponsorships.Where(os => os.CloudSponsor));
Guid? UpdatedOrgId(Guid? orgId) => orgId == organization.Id ? null : organization.Id;
foreach (var sponsorship in sponsorships.Where(os => !os.CloudSponsor))
foreach (var sponsorship in sponsorships)
{
sponsorship.SponsoredOrganizationId = UpdatedOrgId(sponsorship.SponsoredOrganizationId);
sponsorship.SponsoringOrganizationId = UpdatedOrgId(sponsorship.SponsoringOrganizationId);

View File

@ -77,7 +77,11 @@ namespace Bit.Core.Repositories.EntityFramework
var sponsorships = dbContext.OrganizationSponsorships
.Where(os => os.SponsoringOrganizationUserId != default &&
os.SponsoringOrganizationUserId.Value == organizationUserId);
dbContext.RemoveRange(sponsorships);
foreach (var sponsorship in sponsorships)
{
sponsorship.SponsoringOrganizationUserId = null;
}
dbContext.Remove(orgUser);
await dbContext.SaveChangesAsync();
}
@ -92,7 +96,11 @@ namespace Bit.Core.Repositories.EntityFramework
var sponsorships = dbContext.OrganizationSponsorships
.Where(os => os.SponsoringOrganizationUserId != default &&
organizationUserIds.Contains(os.SponsoringOrganizationUserId ?? default));
dbContext.RemoveRange(sponsorships);
foreach (var sponsorship in sponsorships)
{
sponsorship.SponsoringOrganizationUserId = null;
}
dbContext.RemoveRange(entities);
await dbContext.SaveChangesAsync();
}

View File

@ -9,23 +9,13 @@ BEGIN
SET
[SponsoringOrganizationId] = NULL
WHERE
[SponsoringOrganizationId] = @OrganizationId AND
[CloudSponsor] = 0
[SponsoringOrganizationId] = @OrganizationId
UPDATE
[dbo].[OrganizationSponsorship]
SET
[SponsoredOrganizationId] = NULL
WHERE
[SponsoredOrganizationId] = @OrganizationId AND
[CloudSponsor] = 0
DELETE
FROM
[dbo].[OrganizationSponsorship]
WHERE
[CloudSponsor] = 1 AND
([SponsoredOrganizationId] = @OrganizationId OR
[SponsoringOrganizationId] = @OrganizationId)
[SponsoredOrganizationId] = @OrganizationId
END
GO

View File

@ -4,9 +4,12 @@ AS
BEGIN
SET NOCOUNT ON
DELETE
UPDATE
OS
SET
[SponsoringOrganizationUserId] = NULL
FROM
[dbo].[OrganizationSponsorship]
[dbo].[OrganizationSponsorship] OS
WHERE
[SponsoringOrganizationUserId] = @OrganizationUserId
END

View File

@ -4,22 +4,13 @@ AS
BEGIN
SET NOCOUNT ON
DECLARE @BatchSize AS INT;
SET @BatchSize = 100;
WHILE @BatchSize > 0
BEGIN
BEGIN TRANSACTION OrganizationSponsorship_DeleteOUs
DELETE TOP(@BatchSize) OS
FROM
[dbo].[OrganizationSponsorship] OS
INNER JOIN
@SponsoringOrganizationUserIds I ON I.Id = OS.SponsoringOrganizationUserId
SET @BatchSize = @@ROWCOUNT
COMMIT TRANSACTION OrganizationSponsorship_DeleteOUs
END
UPDATE
OS
SET
[SponsoringOrganizationUserId] = NULL
FROM
[dbo].[OrganizationSponsorship] OS
INNER JOIN
@SponsoringOrganizationUserIds I ON I.Id = OS.SponsoringOrganizationUserId
END
GO

View File

@ -0,0 +1,86 @@
-- OrganizationSponsorship_OrganizationDeleted
IF OBJECT_ID('[dbo].[OrganizationSponsorship_OrganizationDeleted]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[OrganizationSponsorship_OrganizationDeleted]
END
GO
CREATE PROCEDURE [dbo].[OrganizationSponsorship_OrganizationDeleted]
@OrganizationId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
UPDATE
[dbo].[OrganizationSponsorship]
SET
[SponsoringOrganizationId] = NULL
WHERE
[SponsoringOrganizationId] = @OrganizationId AND
[CloudSponsor] = 0
UPDATE
[dbo].[OrganizationSponsorship]
SET
[SponsoredOrganizationId] = NULL
WHERE
[SponsoredOrganizationId] = @OrganizationId AND
[CloudSponsor] = 0
DELETE
FROM
[dbo].[OrganizationSponsorship]
WHERE
[CloudSponsor] = 1 AND
([SponsoredOrganizationId] = @OrganizationId OR
[SponsoringOrganizationId] = @OrganizationId)
END
GO
-- OrganizationSponsorship_OrganizationUserDeleted
IF OBJECT_ID('[dbo].[OrganizationSponsorship_OrganizationUserDeleted]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[OrganizationSponsorship_OrganizationUserDeleted]
END
GO
CREATE PROCEDURE [dbo].[OrganizationSponsorship_OrganizationUserDeleted]
@OrganizationUserId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
UPDATE
OS
SET
[SponsoringOrganizationUserId] = NULL
FROM
[dbo].[OrganizationSponsorship] OS
WHERE
[SponsoringOrganizationUserId] = @OrganizationUserId
END
GO
-- OrganizationSponsorship_OrganizationUsersDeleted
IF OBJECT_ID('[dbo].[OrganizationSponsorship_OrganizationUsersDeleted]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[OrganizationSponsorship_OrganizationUsersDeleted]
END
GO
CREATE PROCEDURE [dbo].[OrganizationSponsorship_OrganizationUsersDeleted]
@SponsoringOrganizationUserIds [dbo].[GuidIdArray] READONLY
AS
BEGIN
SET NOCOUNT ON
UPDATE
OS
SET
[SponsoringOrganizationUserId] = NULL
FROM
[dbo].[OrganizationSponsorship] OS
INNER JOIN
@SponsoringOrganizationUserIds I ON I.Id = OS.SponsoringOrganizationUserId
END
GO