1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-02 08:32:50 -05:00

Families for enterprise/stripe integrations (#1699)

* Add PlanSponsorshipType to static store

* Add sponsorship type to token and creates sponsorship

* PascalCase properties

* Require sponsorship for remove

* Create subscription sponsorship helper class

* Handle Sponsored subscription changes

* Add sponsorship id to subscription metadata

* Make sponsoring references nullable

This state indicates that a sponsorship has lapsed, but was not able to
be reverted for billing reasons

* WIP: Validate and remove subscriptions

* Update sponsorships on organization and org user delete

* Add friendly name to organization sponsorship
This commit is contained in:
Matt Gibson
2021-11-08 17:01:09 -06:00
committed by Justin Baur
parent 143be4273b
commit 45f6ec1781
42 changed files with 1060 additions and 188 deletions

View File

@ -4,9 +4,10 @@ BEGIN
CREATE TABLE [dbo].[OrganizationSponsorship] (
[Id] UNIQUEIDENTIFIER NOT NULL,
[InstallationId] UNIQUEIDENTIFIER NULL,
[SponsoringOrganizationId] UNIQUEIDENTIFIER NOT NULL,
[SponsoringOrganizationUserID] UNIQUEIDENTIFIER NOT NULL,
[SponsoringOrganizationId] UNIQUEIDENTIFIER NULL,
[SponsoringOrganizationUserID] UNIQUEIDENTIFIER NULL,
[SponsoredOrganizationId] UNIQUEIDENTIFIER NULL,
[FriendlyName] NVARCHAR(256) NULL,
[OfferedToEmail] NVARCHAR (256) NULL,
[PlanSponsorshipType] TINYINT NULL,
[CloudSponsor] BIT NULL,
@ -35,6 +36,7 @@ IF NOT EXISTS(SELECT name FROM sys.indexes WHERE name = 'IX_OrganizationSponsors
BEGIN
CREATE NONCLUSTERED INDEX [IX_OrganizationSponsorship_SponsoringOrganizationId]
ON [dbo].[OrganizationSponsorship]([SponsoringOrganizationId] ASC)
WHERE [SponsoringOrganizationId] IS NOT NULL;
END
GO
@ -42,6 +44,7 @@ IF NOT EXISTS(SELECT name FROM sys.indexes WHERE name = 'IX_OrganizationSponsors
BEGIN
CREATE NONCLUSTERED INDEX [IX_OrganizationSponsorship_SponsoringOrganizationUserId]
ON [dbo].[OrganizationSponsorship]([SponsoringOrganizationUserID] ASC)
WHERE [SponsoringOrganizationUserID] IS NOT NULL;
END
GO
@ -114,6 +117,7 @@ CREATE PROCEDURE [dbo].[OrganizationSponsorship_Create]
@SponsoringOrganizationId UNIQUEIDENTIFIER,
@SponsoringOrganizationUserID UNIQUEIDENTIFIER,
@SponsoredOrganizationId UNIQUEIDENTIFIER,
@FriendlyName NVARCHAR(256),
@OfferedToEmail NVARCHAR(256),
@PlanSponsorshipType TINYINT,
@CloudSponsor BIT,
@ -131,6 +135,7 @@ BEGIN
[SponsoringOrganizationId],
[SponsoringOrganizationUserID],
[SponsoredOrganizationId],
[FriendlyName],
[OfferedToEmail],
[PlanSponsorshipType],
[CloudSponsor],
@ -145,6 +150,7 @@ BEGIN
@SponsoringOrganizationId,
@SponsoringOrganizationUserID,
@SponsoredOrganizationId,
@FriendlyName,
@OfferedToEmail,
@PlanSponsorshipType,
@CloudSponsor,
@ -168,6 +174,7 @@ CREATE PROCEDURE [dbo].[OrganizationSponsorship_Update]
@SponsoringOrganizationId UNIQUEIDENTIFIER,
@SponsoringOrganizationUserID UNIQUEIDENTIFIER,
@SponsoredOrganizationId UNIQUEIDENTIFIER,
@FriendlyName NVARCHAR(256),
@OfferedToEmail NVARCHAR(256),
@PlanSponsorshipType TINYINT,
@CloudSponsor BIT,
@ -185,6 +192,7 @@ BEGIN
[SponsoringOrganizationId] = @SponsoringOrganizationId,
[SponsoringOrganizationUserID] = @SponsoringOrganizationUserID,
[SponsoredOrganizationId] = @SponsoredOrganizationId,
[FriendlyName] = @FriendlyName,
[OfferedToEmail] = @OfferedToEmail,
[PlanSponsorshipType] = @PlanSponsorshipType,
[CloudSponsor] = @CloudSponsor,
@ -290,3 +298,365 @@ BEGIN
[OfferedToEmail] = @OfferedToEmail
END
GO
-- 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
DELETE
FROM
[dbo].[OrganizationSponsorship]
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
DECLARE @BatchSize INT = 100
WHILE @BatchSize > 0
BEGIN
BEGIN TRANSACTION OS_DeleteMany_OUs
DELETE TOP(@BatchSize) OS
FROM
[dbo].[OrganizationSponsorship] OS
INNER JOIN
@SponsoringOrganizationUserIds I ON I.Id = OS.SponsoringOrganizationUserId
SET @BatchSize = @@ROWCOUNT
COMMIT TRANSACTION OS_DeleteMany_OUs
END
END
GO
-- Update Organization delete sprocs to handle organization sponsorships
IF OBJECT_ID('[dbo].[Organization_DeleteById]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[Organization_DeleteById]
END
GO
CREATE PROCEDURE [dbo].[Organization_DeleteById]
@Id UNIQUEIDENTIFIER
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].[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
FROM
[dbo].[OrganizationUser]
WHERE
[OrganizationId] = @Id
DELETE
FROM
[dbo].[ProviderOrganization]
WHERE
[OrganizationId] = @Id
EXEC[dbo].[OrganizationSponsorship_OrganizationDeleted] @Id
DELETE
FROM
[dbo].[Organization]
WHERE
[Id] = @Id
COMMIT TRANSACTION Organization_DeleteById
END
GO
-- Update Organization User delete sprocs to handle organization sponsorships
IF OBJECT_ID('[dbo].[OrganizationUser_DeleteById]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[OrganizationUser_DeleteById]
END
GO
CREATE PROCEDURE [dbo].[OrganizationUser_DeleteById]
@Id UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Id
DECLARE @OrganizationId UNIQUEIDENTIFIER
DECLARE @UserId UNIQUEIDENTIFIER
SELECT
@OrganizationId = [OrganizationId],
@UserId = [UserId]
FROM
[dbo].[OrganizationUser]
WHERE
[Id] = @Id
IF @OrganizationId IS NOT NULL AND @UserId IS NOT NULL
BEGIN
EXEC [dbo].[SsoUser_Delete] @UserId, @OrganizationId
END
DELETE
FROM
[dbo].[CollectionUser]
WHERE
[OrganizationUserId] = @Id
DELETE
FROM
[dbo].[GroupUser]
WHERE
[OrganizationUserId] = @Id
EXEC [dbo].[OrganizationUser_DeleteById] @Id
DELETE
FROM
[dbo].[OrganizationUser]
WHERE
[Id] = @Id
END
GO
IF OBJECT_ID('[dbo].[OrganizationUser_DeleteByIds]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[OrganizationUser_DeleteByIds]
END
GO
CREATE PROCEDURE [dbo].[OrganizationUser_DeleteByIds]
@Ids [dbo].[GuidIdArray] READONLY
AS
BEGIN
SET NOCOUNT ON
EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserIds] @Ids
DECLARE @UserAndOrganizationIds [dbo].[TwoGuidIdArray]
INSERT INTO @UserAndOrganizationIds
(Id1, Id2)
SELECT
UserId,
OrganizationId
FROM
[dbo].[OrganizationUser] OU
INNER JOIN
@Ids OUIds ON OUIds.Id = OU.Id
WHERE
UserId IS NOT NULL AND
OrganizationId IS NOT NULL
BEGIN
EXEC [dbo].[SsoUser_DeleteMany] @UserAndOrganizationIds
END
DECLARE @BatchSize INT = 100
-- Delete CollectionUsers
WHILE @BatchSize > 0
BEGIN
BEGIN TRANSACTION CollectionUser_DeleteMany_CUs
DELETE TOP(@BatchSize) CU
FROM
[dbo].[CollectionUser] CU
INNER JOIN
@Ids I ON I.Id = CU.OrganizationUserId
SET @BatchSize = @@ROWCOUNT
COMMIT TRANSACTION CollectionUser_DeleteMany_CUs
END
SET @BatchSize = 100;
-- Delete GroupUsers
WHILE @BatchSize > 0
BEGIN
BEGIN TRANSACTION GroupUser_DeleteMany_GroupUsers
DELETE TOP(@BatchSize) GU
FROM
[dbo].[GroupUser] GU
INNER JOIN
@Ids I ON I.Id = GU.OrganizationUserId
SET @BatchSize = @@ROWCOUNT
COMMIT TRANSACTION GoupUser_DeleteMany_GroupUsers
END
EXEC [dbo].[OrganizationSponsorship_OrganizationUsersDeleted] @Ids
SET @BatchSize = 100;
-- Delete OrganizationUsers
WHILE @BatchSize > 0
BEGIN
BEGIN TRANSACTION OrganizationUser_DeleteMany_OUs
DELETE TOP(@BatchSize) OU
FROM
[dbo].[OrganizationUser] OU
INNER JOIN
@Ids I ON I.Id = OU.Id
SET @BatchSize = @@ROWCOUNT
COMMIT TRANSACTION OrganizationUser_DeleteMany_OUs
END
END
GO
-- OrganizationUserOrganizationDetailsView update
ALTER VIEW [dbo].[OrganizationUserOrganizationDetailsView]
AS
SELECT
OU.[UserId],
OU.[OrganizationId],
O.[Name],
O.[Enabled],
O.[UsePolicies],
O.[UseSso],
O.[UseGroups],
O.[UseDirectory],
O.[UseEvents],
O.[UseTotp],
O.[Use2fa],
O.[UseApi],
O.[UseResetPassword],
O.[SelfHost],
O.[UsersGetPremium],
O.[Seats],
O.[MaxCollections],
O.[MaxStorageGb],
O.[Identifier],
OU.[Key],
OU.[ResetPasswordKey],
O.[PublicKey],
O.[PrivateKey],
OU.[Status],
OU.[Type],
SU.[ExternalId] SsoExternalId,
OU.[Permissions],
PO.[ProviderId],
P.[Name] ProviderName,
OS.[FriendlyName] FamilySponsorshipFriendlyName
FROM
[dbo].[OrganizationUser] OU
INNER JOIN
[dbo].[Organization] O ON O.[Id] = OU.[OrganizationId]
LEFT JOIN
[dbo].[SsoUser] SU ON SU.[UserId] = OU.[UserId] AND SU.[OrganizationId] = OU.[OrganizationId]
LEFT JOIN
[dbo].[ProviderOrganization] PO ON PO.[OrganizationId] = O.[Id]
LEFT JOIN
[dbo].[Provider] P ON P.[Id] = PO.[ProviderId]
LEFT JOIN
[dbo].[OrganizationSponsorship] OS ON OS.[SponsoringOrganizationUserId] = OU.[Id]

View File

@ -9,7 +9,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Bit.MySqlMigrations.Migrations
{
[DbContext(typeof(DatabaseContext))]
[Migration("20211104164838_OrganizationSponsorship")]
[Migration("20211108225243_OrganizationSponsorship")]
partial class OrganizationSponsorship
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -595,6 +595,10 @@ namespace Bit.MySqlMigrations.Migrations
b.Property<bool>("CloudSponsor")
.HasColumnType("tinyint(1)");
b.Property<string>("FriendlyName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<Guid?>("InstallationId")
.HasColumnType("char(36)");
@ -611,10 +615,10 @@ namespace Bit.MySqlMigrations.Migrations
b.Property<Guid?>("SponsoredOrganizationId")
.HasColumnType("char(36)");
b.Property<Guid>("SponsoringOrganizationId")
b.Property<Guid?>("SponsoringOrganizationId")
.HasColumnType("char(36)");
b.Property<Guid>("SponsoringOrganizationUserId")
b.Property<Guid?>("SponsoringOrganizationUserId")
.HasColumnType("char(36)");
b.Property<DateTime?>("SponsorshipLapsedDate")
@ -1356,9 +1360,7 @@ namespace Bit.MySqlMigrations.Migrations
b.HasOne("Bit.Core.Models.EntityFramework.Organization", "SponsoringOrganization")
.WithMany()
.HasForeignKey("SponsoringOrganizationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("SponsoringOrganizationId");
b.Navigation("Installation");

View File

@ -20,9 +20,11 @@ namespace Bit.MySqlMigrations.Migrations
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
InstallationId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
SponsoringOrganizationId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
SponsoringOrganizationUserId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
SponsoringOrganizationId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
SponsoringOrganizationUserId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
SponsoredOrganizationId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
FriendlyName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
OfferedToEmail = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
PlanSponsorshipType = table.Column<byte>(type: "tinyint unsigned", nullable: true),
@ -51,7 +53,7 @@ namespace Bit.MySqlMigrations.Migrations
column: x => x.SponsoringOrganizationId,
principalTable: "Organization",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
onDelete: ReferentialAction.Restrict);
})
.Annotation("MySql:CharSet", "utf8mb4");

View File

@ -593,6 +593,10 @@ namespace Bit.MySqlMigrations.Migrations
b.Property<bool>("CloudSponsor")
.HasColumnType("tinyint(1)");
b.Property<string>("FriendlyName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<Guid?>("InstallationId")
.HasColumnType("char(36)");
@ -609,10 +613,10 @@ namespace Bit.MySqlMigrations.Migrations
b.Property<Guid?>("SponsoredOrganizationId")
.HasColumnType("char(36)");
b.Property<Guid>("SponsoringOrganizationId")
b.Property<Guid?>("SponsoringOrganizationId")
.HasColumnType("char(36)");
b.Property<Guid>("SponsoringOrganizationUserId")
b.Property<Guid?>("SponsoringOrganizationUserId")
.HasColumnType("char(36)");
b.Property<DateTime?>("SponsorshipLapsedDate")
@ -1354,9 +1358,7 @@ namespace Bit.MySqlMigrations.Migrations
b.HasOne("Bit.Core.Models.EntityFramework.Organization", "SponsoringOrganization")
.WithMany()
.HasForeignKey("SponsoringOrganizationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("SponsoringOrganizationId");
b.Navigation("Installation");

View File

@ -5,9 +5,10 @@ ALTER TABLE `User` ADD `UsesCryptoAgent` tinyint(1) NOT NULL DEFAULT FALSE;
CREATE TABLE `OrganizationSponsorship` (
`Id` char(36) COLLATE ascii_general_ci NOT NULL,
`InstallationId` char(36) COLLATE ascii_general_ci NULL,
`SponsoringOrganizationId` char(36) COLLATE ascii_general_ci NOT NULL,
`SponsoringOrganizationUserId` char(36) COLLATE ascii_general_ci NOT NULL,
`SponsoringOrganizationId` char(36) COLLATE ascii_general_ci NULL,
`SponsoringOrganizationUserId` char(36) COLLATE ascii_general_ci NULL,
`SponsoredOrganizationId` char(36) COLLATE ascii_general_ci NULL,
`FriendlyName` varchar(256) CHARACTER SET utf8mb4 NULL,
`OfferedToEmail` varchar(256) CHARACTER SET utf8mb4 NULL,
`PlanSponsorshipType` tinyint unsigned NULL,
`CloudSponsor` tinyint(1) NOT NULL,
@ -17,7 +18,7 @@ CREATE TABLE `OrganizationSponsorship` (
CONSTRAINT `PK_OrganizationSponsorship` PRIMARY KEY (`Id`),
CONSTRAINT `FK_OrganizationSponsorship_Installation_InstallationId` FOREIGN KEY (`InstallationId`) REFERENCES `Installation` (`Id`) ON DELETE RESTRICT,
CONSTRAINT `FK_OrganizationSponsorship_Organization_SponsoredOrganizationId` FOREIGN KEY (`SponsoredOrganizationId`) REFERENCES `Organization` (`Id`) ON DELETE RESTRICT,
CONSTRAINT `FK_OrganizationSponsorship_Organization_SponsoringOrganizationId` FOREIGN KEY (`SponsoringOrganizationId`) REFERENCES `Organization` (`Id`) ON DELETE CASCADE
CONSTRAINT `FK_OrganizationSponsorship_Organization_SponsoringOrganizationId` FOREIGN KEY (`SponsoringOrganizationId`) REFERENCES `Organization` (`Id`) ON DELETE RESTRICT
) CHARACTER SET utf8mb4;
CREATE INDEX `IX_OrganizationSponsorship_InstallationId` ON `OrganizationSponsorship` (`InstallationId`);
@ -27,6 +28,6 @@ CREATE INDEX `IX_OrganizationSponsorship_SponsoredOrganizationId` ON `Organizati
CREATE INDEX `IX_OrganizationSponsorship_SponsoringOrganizationId` ON `OrganizationSponsorship` (`SponsoringOrganizationId`);
INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`)
VALUES ('20211104164838_OrganizationSponsorship', '5.0.9');
VALUES ('20211108225243_OrganizationSponsorship', '5.0.9');
COMMIT;

View File

@ -10,7 +10,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Bit.PostgresMigrations.Migrations
{
[DbContext(typeof(DatabaseContext))]
[Migration("20211104164532_OrganizationSponsorship")]
[Migration("20211108225011_OrganizationSponsorship")]
partial class OrganizationSponsorship
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -599,6 +599,10 @@ namespace Bit.PostgresMigrations.Migrations
b.Property<bool>("CloudSponsor")
.HasColumnType("boolean");
b.Property<string>("FriendlyName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<Guid?>("InstallationId")
.HasColumnType("uuid");
@ -615,10 +619,10 @@ namespace Bit.PostgresMigrations.Migrations
b.Property<Guid?>("SponsoredOrganizationId")
.HasColumnType("uuid");
b.Property<Guid>("SponsoringOrganizationId")
b.Property<Guid?>("SponsoringOrganizationId")
.HasColumnType("uuid");
b.Property<Guid>("SponsoringOrganizationUserId")
b.Property<Guid?>("SponsoringOrganizationUserId")
.HasColumnType("uuid");
b.Property<DateTime?>("SponsorshipLapsedDate")
@ -1365,9 +1369,7 @@ namespace Bit.PostgresMigrations.Migrations
b.HasOne("Bit.Core.Models.EntityFramework.Organization", "SponsoringOrganization")
.WithMany()
.HasForeignKey("SponsoringOrganizationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("SponsoringOrganizationId");
b.Navigation("Installation");

View File

@ -20,9 +20,10 @@ namespace Bit.PostgresMigrations.Migrations
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
InstallationId = table.Column<Guid>(type: "uuid", nullable: true),
SponsoringOrganizationId = table.Column<Guid>(type: "uuid", nullable: false),
SponsoringOrganizationUserId = table.Column<Guid>(type: "uuid", nullable: false),
SponsoringOrganizationId = table.Column<Guid>(type: "uuid", nullable: true),
SponsoringOrganizationUserId = table.Column<Guid>(type: "uuid", nullable: true),
SponsoredOrganizationId = table.Column<Guid>(type: "uuid", nullable: true),
FriendlyName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
OfferedToEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
PlanSponsorshipType = table.Column<byte>(type: "smallint", nullable: true),
CloudSponsor = table.Column<bool>(type: "boolean", nullable: false),
@ -50,7 +51,7 @@ namespace Bit.PostgresMigrations.Migrations
column: x => x.SponsoringOrganizationId,
principalTable: "Organization",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(

View File

@ -597,6 +597,10 @@ namespace Bit.PostgresMigrations.Migrations
b.Property<bool>("CloudSponsor")
.HasColumnType("boolean");
b.Property<string>("FriendlyName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<Guid?>("InstallationId")
.HasColumnType("uuid");
@ -613,10 +617,10 @@ namespace Bit.PostgresMigrations.Migrations
b.Property<Guid?>("SponsoredOrganizationId")
.HasColumnType("uuid");
b.Property<Guid>("SponsoringOrganizationId")
b.Property<Guid?>("SponsoringOrganizationId")
.HasColumnType("uuid");
b.Property<Guid>("SponsoringOrganizationUserId")
b.Property<Guid?>("SponsoringOrganizationUserId")
.HasColumnType("uuid");
b.Property<DateTime?>("SponsorshipLapsedDate")
@ -1363,9 +1367,7 @@ namespace Bit.PostgresMigrations.Migrations
b.HasOne("Bit.Core.Models.EntityFramework.Organization", "SponsoringOrganization")
.WithMany()
.HasForeignKey("SponsoringOrganizationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("SponsoringOrganizationId");
b.Navigation("Installation");

View File

@ -5,9 +5,10 @@ ALTER TABLE "User" ADD "UsesCryptoAgent" boolean NOT NULL DEFAULT FALSE;
CREATE TABLE "OrganizationSponsorship" (
"Id" uuid NOT NULL,
"InstallationId" uuid NULL,
"SponsoringOrganizationId" uuid NOT NULL,
"SponsoringOrganizationUserId" uuid NOT NULL,
"SponsoringOrganizationId" uuid NULL,
"SponsoringOrganizationUserId" uuid NULL,
"SponsoredOrganizationId" uuid NULL,
"FriendlyName" character varying(256) NULL,
"OfferedToEmail" character varying(256) NULL,
"PlanSponsorshipType" smallint NULL,
"CloudSponsor" boolean NOT NULL,
@ -17,7 +18,7 @@ CREATE TABLE "OrganizationSponsorship" (
CONSTRAINT "PK_OrganizationSponsorship" PRIMARY KEY ("Id"),
CONSTRAINT "FK_OrganizationSponsorship_Installation_InstallationId" FOREIGN KEY ("InstallationId") REFERENCES "Installation" ("Id") ON DELETE RESTRICT,
CONSTRAINT "FK_OrganizationSponsorship_Organization_SponsoredOrganizationId" FOREIGN KEY ("SponsoredOrganizationId") REFERENCES "Organization" ("Id") ON DELETE RESTRICT,
CONSTRAINT "FK_OrganizationSponsorship_Organization_SponsoringOrganization~" FOREIGN KEY ("SponsoringOrganizationId") REFERENCES "Organization" ("Id") ON DELETE CASCADE
CONSTRAINT "FK_OrganizationSponsorship_Organization_SponsoringOrganization~" FOREIGN KEY ("SponsoringOrganizationId") REFERENCES "Organization" ("Id") ON DELETE RESTRICT
);
CREATE INDEX "IX_OrganizationSponsorship_InstallationId" ON "OrganizationSponsorship" ("InstallationId");
@ -27,6 +28,6 @@ CREATE INDEX "IX_OrganizationSponsorship_SponsoredOrganizationId" ON "Organizati
CREATE INDEX "IX_OrganizationSponsorship_SponsoringOrganizationId" ON "OrganizationSponsorship" ("SponsoringOrganizationId");
INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20211104164532_OrganizationSponsorship', '5.0.9');
VALUES ('20211108225011_OrganizationSponsorship', '5.0.9');
COMMIT;