From 51fd87df0b9f94390872405f57dbf4efa5e3a744 Mon Sep 17 00:00:00 2001
From: Matt Portune <59324545+mportune-bw@users.noreply.github.com>
Date: Wed, 22 Jul 2020 09:38:39 -0400
Subject: [PATCH] Added UseSso bool to Organization (#834)
* Added UseSso bool to org
* Update fields in migration script
* bump version & check enabled flag on ssoConfig
---
src/Admin/Models/OrganizationEditModel.cs | 4 +
src/Admin/Views/Organizations/Edit.cshtml | 5 +
src/Core/Enums/PlanType.cs | 6 +-
.../Api/Response/OrganizationResponseModel.cs | 2 +
.../ProfileOrganizationResponseModel.cs | 4 +-
.../Models/Business/OrganizationLicense.cs | 17 +-
.../OrganizationUserOrganizationDetails.cs | 1 +
src/Core/Models/StaticStore/Plan.cs | 1 +
src/Core/Models/Table/Organization.cs | 1 +
.../Implementations/OrganizationService.cs | 26 ++
.../Stored Procedures/Organization_Create.sql | 3 +
.../Stored Procedures/Organization_Update.sql | 2 +
src/Sql/dbo/Tables/Organization.sql | 1 +
...rganizationUserOrganizationDetailsView.sql | 1 +
.../Services/OrganizationServiceTests.cs | 6 +-
.../DbScripts/2020-07-20_00_OrgSso.sql | 292 ++++++++++++++++++
16 files changed, 364 insertions(+), 8 deletions(-)
create mode 100644 util/Migrator/DbScripts/2020-07-20_00_OrgSso.sql
diff --git a/src/Admin/Models/OrganizationEditModel.cs b/src/Admin/Models/OrganizationEditModel.cs
index 25c3dbe34..7f32f86e6 100644
--- a/src/Admin/Models/OrganizationEditModel.cs
+++ b/src/Admin/Models/OrganizationEditModel.cs
@@ -30,6 +30,7 @@ namespace Bit.Admin.Models
Seats = org.Seats;
MaxCollections = org.MaxCollections;
UsePolicies = org.UsePolicies;
+ UseSso = org.UseSso;
UseGroups = org.UseGroups;
UseDirectory = org.UseDirectory;
UseEvents = org.UseEvents;
@@ -71,6 +72,8 @@ namespace Bit.Admin.Models
public short? MaxCollections { get; set; }
[Display(Name = "Policies")]
public bool UsePolicies { get; set; }
+ [Display(Name = "SSO")]
+ public bool UseSso { get; set; }
[Display(Name = "Groups")]
public bool UseGroups { get; set; }
[Display(Name = "Directory")]
@@ -112,6 +115,7 @@ namespace Bit.Admin.Models
existingOrganization.Seats = Seats;
existingOrganization.MaxCollections = MaxCollections;
existingOrganization.UsePolicies = UsePolicies;
+ existingOrganization.UseSso = UseSso;
existingOrganization.UseGroups = UseGroups;
existingOrganization.UseDirectory = UseDirectory;
existingOrganization.UseEvents = UseEvents;
diff --git a/src/Admin/Views/Organizations/Edit.cshtml b/src/Admin/Views/Organizations/Edit.cshtml
index 626008bf8..17fd83ba2 100644
--- a/src/Admin/Views/Organizations/Edit.cshtml
+++ b/src/Admin/Views/Organizations/Edit.cshtml
@@ -22,6 +22,7 @@
document.getElementById('@(nameof(Model.MaxStorageGb))').value = '1';
// Features
document.getElementById('@(nameof(Model.UsePolicies))').checked = true;
+ document.getElementById('@(nameof(Model.UseSso))').checked = true;
document.getElementById('@(nameof(Model.UseGroups))').checked = true;
document.getElementById('@(nameof(Model.UseDirectory))').checked = true;
document.getElementById('@(nameof(Model.UseEvents))').checked = true;
@@ -165,6 +166,10 @@
+
+
+
+
diff --git a/src/Core/Enums/PlanType.cs b/src/Core/Enums/PlanType.cs
index df02b8bf7..de42d30b7 100644
--- a/src/Core/Enums/PlanType.cs
+++ b/src/Core/Enums/PlanType.cs
@@ -17,6 +17,10 @@ namespace Bit.Core.Enums
[Display(Name = "Enterprise (Annually)")]
EnterpriseAnnually = 5,
[Display(Name = "Custom")]
- Custom = 6
+ Custom = 6,
+ [Display(Name = "PLACEHOLDER")]
+ SsoPlaceholderMonthly = 10,
+ [Display(Name = "PLACEHOLDER")]
+ SsoPlaceholderAnnually = 11,
}
}
diff --git a/src/Core/Models/Api/Response/OrganizationResponseModel.cs b/src/Core/Models/Api/Response/OrganizationResponseModel.cs
index e489be557..63f781d3b 100644
--- a/src/Core/Models/Api/Response/OrganizationResponseModel.cs
+++ b/src/Core/Models/Api/Response/OrganizationResponseModel.cs
@@ -31,6 +31,7 @@ namespace Bit.Core.Models.Api
MaxCollections = organization.MaxCollections;
MaxStorageGb = organization.MaxStorageGb;
UsePolicies = organization.UsePolicies;
+ UseSso = organization.UseSso;
UseGroups = organization.UseGroups;
UseDirectory = organization.UseDirectory;
UseEvents = organization.UseEvents;
@@ -56,6 +57,7 @@ namespace Bit.Core.Models.Api
public short? MaxCollections { get; set; }
public short? MaxStorageGb { get; set; }
public bool UsePolicies { get; set; }
+ public bool UseSso { get; set; }
public bool UseGroups { get; set; }
public bool UseDirectory { get; set; }
public bool UseEvents { get; set; }
diff --git a/src/Core/Models/Api/Response/ProfileOrganizationResponseModel.cs b/src/Core/Models/Api/Response/ProfileOrganizationResponseModel.cs
index 050183aa1..3178f1486 100644
--- a/src/Core/Models/Api/Response/ProfileOrganizationResponseModel.cs
+++ b/src/Core/Models/Api/Response/ProfileOrganizationResponseModel.cs
@@ -11,6 +11,7 @@ namespace Bit.Core.Models.Api
Id = organization.OrganizationId.ToString();
Name = organization.Name;
UsePolicies = organization.UsePolicies;
+ UseSso = organization.UseSso;
UseGroups = organization.UseGroups;
UseDirectory = organization.UseDirectory;
UseEvents = organization.UseEvents;
@@ -31,13 +32,14 @@ namespace Bit.Core.Models.Api
public string Id { get; set; }
public string Name { get; set; }
public bool UsePolicies { get; set; }
+ public bool UseSso { get; set; }
public bool UseGroups { get; set; }
public bool UseDirectory { get; set; }
public bool UseEvents { get; set; }
public bool UseTotp { get; set; }
public bool Use2fa { get; set; }
public bool UseApi { get; set; }
- public bool UseBusinessPortal => UsePolicies; // TODO add events if needed, add SSO when created
+ public bool UseBusinessPortal => UsePolicies || UseSso; // TODO add events if needed
public bool UsersGetPremium { get; set; }
public bool SelfHost { get; set; }
public int Seats { get; set; }
diff --git a/src/Core/Models/Business/OrganizationLicense.cs b/src/Core/Models/Business/OrganizationLicense.cs
index d02dc7948..3e191ef32 100644
--- a/src/Core/Models/Business/OrganizationLicense.cs
+++ b/src/Core/Models/Business/OrganizationLicense.cs
@@ -19,7 +19,7 @@ namespace Bit.Core.Models.Business
public OrganizationLicense(Organization org, SubscriptionInfo subscriptionInfo, Guid installationId,
ILicensingService licenseService)
{
- Version = 5; // TODO: bump to version 6
+ Version = 6; // TODO: bump to version 7
LicenseKey = org.LicenseKey;
InstallationId = installationId;
Id = org.Id;
@@ -32,6 +32,7 @@ namespace Bit.Core.Models.Business
Seats = org.Seats;
MaxCollections = org.MaxCollections;
UsePolicies = org.UsePolicies;
+ UseSso = org.UseSso;
UseGroups = org.UseGroups;
UseEvents = org.UseEvents;
UseDirectory = org.UseDirectory;
@@ -100,6 +101,7 @@ namespace Bit.Core.Models.Business
public short? Seats { get; set; }
public short? MaxCollections { get; set; }
public bool UsePolicies { get; set; }
+ public bool UseSso { get; set; }
public bool UseGroups { get; set; }
public bool UseEvents { get; set; }
public bool UseDirectory { get; set; }
@@ -122,7 +124,7 @@ namespace Bit.Core.Models.Business
public byte[] GetDataBytes(bool forHash = false)
{
string data = null;
- if (Version >= 1 && Version <= 6)
+ if (Version >= 1 && Version <= 7)
{
var props = typeof(OrganizationLicense)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
@@ -139,6 +141,8 @@ namespace Bit.Core.Models.Business
(Version >= 5 || !p.Name.Equals(nameof(UseApi))) &&
// UsePolicies was added in Version 6
(Version >= 6 || !p.Name.Equals(nameof(UsePolicies))) &&
+ // UseSso was added in Version 7
+ (Version >= 7 || !p.Name.Equals(nameof(UseSso))) &&
(
!forHash ||
(
@@ -175,7 +179,7 @@ namespace Bit.Core.Models.Business
return false;
}
- if (Version >= 1 && Version <= 6)
+ if (Version >= 1 && Version <= 7)
{
return InstallationId == globalSettings.Installation.Id && SelfHost;
}
@@ -192,7 +196,7 @@ namespace Bit.Core.Models.Business
return false;
}
- if (Version >= 1 && Version <= 6)
+ if (Version >= 1 && Version <= 7)
{
var valid =
globalSettings.Installation.Id == InstallationId &&
@@ -231,6 +235,11 @@ namespace Bit.Core.Models.Business
{
valid = organization.UsePolicies == UsePolicies;
}
+
+ if (valid && Version >= 7)
+ {
+ valid = organization.UseSso == UseSso;
+ }
return valid;
}
diff --git a/src/Core/Models/Data/OrganizationUserOrganizationDetails.cs b/src/Core/Models/Data/OrganizationUserOrganizationDetails.cs
index c67daa560..9b336ec9c 100644
--- a/src/Core/Models/Data/OrganizationUserOrganizationDetails.cs
+++ b/src/Core/Models/Data/OrganizationUserOrganizationDetails.cs
@@ -8,6 +8,7 @@ namespace Bit.Core.Models.Data
public Guid? UserId { get; set; }
public string Name { get; set; }
public bool UsePolicies { get; set; }
+ public bool UseSso { get; set; }
public bool UseGroups { get; set; }
public bool UseDirectory { get; set; }
public bool UseEvents { get; set; }
diff --git a/src/Core/Models/StaticStore/Plan.cs b/src/Core/Models/StaticStore/Plan.cs
index cf0bcfb39..11cdfd8db 100644
--- a/src/Core/Models/StaticStore/Plan.cs
+++ b/src/Core/Models/StaticStore/Plan.cs
@@ -16,6 +16,7 @@ namespace Bit.Core.Models.StaticStore
public bool CanBuyPremiumAccessAddon { get; set; }
public bool UseGroups { get; set; }
public bool UsePolicies { get; set; }
+ public bool UseSso { get; set; }
public bool UseDirectory { get; set; }
public bool UseEvents { get; set; }
public bool UseTotp { get; set; }
diff --git a/src/Core/Models/Table/Organization.cs b/src/Core/Models/Table/Organization.cs
index 75b8c380b..cd0f3546a 100644
--- a/src/Core/Models/Table/Organization.cs
+++ b/src/Core/Models/Table/Organization.cs
@@ -26,6 +26,7 @@ namespace Bit.Core.Models.Table
public short? Seats { get; set; }
public short? MaxCollections { get; set; }
public bool UsePolicies { get; set; }
+ public bool UseSso { get; set; }
public bool UseGroups { get; set; }
public bool UseDirectory { get; set; }
public bool UseEvents { get; set; }
diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs
index 8ec6703de..184f9f5e0 100644
--- a/src/Core/Services/Implementations/OrganizationService.cs
+++ b/src/Core/Services/Implementations/OrganizationService.cs
@@ -34,6 +34,7 @@ namespace Bit.Core.Services
private readonly IApplicationCacheService _applicationCacheService;
private readonly IPaymentService _paymentService;
private readonly IPolicyRepository _policyRepository;
+ private readonly ISsoConfigRepository _ssoConfigRepository;
private readonly IReferenceEventService _referenceEventService;
private readonly GlobalSettings _globalSettings;
@@ -54,6 +55,7 @@ namespace Bit.Core.Services
IApplicationCacheService applicationCacheService,
IPaymentService paymentService,
IPolicyRepository policyRepository,
+ ISsoConfigRepository ssoConfigRepository,
IReferenceEventService referenceEventService,
GlobalSettings globalSettings)
{
@@ -73,6 +75,7 @@ namespace Bit.Core.Services
_applicationCacheService = applicationCacheService;
_paymentService = paymentService;
_policyRepository = policyRepository;
+ _ssoConfigRepository = ssoConfigRepository;
_referenceEventService = referenceEventService;
_globalSettings = globalSettings;
}
@@ -216,6 +219,16 @@ namespace Bit.Core.Services
$"Disable your policies.");
}
}
+
+ if (!newPlan.UseSso && organization.UseSso)
+ {
+ var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(organization.Id);
+ if (ssoConfig != null && ssoConfig.Enabled)
+ {
+ throw new BadRequestException($"Your new plan does not allow the SSO feature. " +
+ $"Disable your SSO configuration.");
+ }
+ }
// TODO: Check storage?
@@ -504,6 +517,7 @@ namespace Bit.Core.Services
MaxStorageGb = !plan.MaxStorageGb.HasValue ?
(short?)null : (short)(plan.MaxStorageGb.Value + signup.AdditionalStorageGb),
UsePolicies = plan.UsePolicies,
+ UseSso = plan.UseSso,
UseGroups = plan.UseGroups,
UseEvents = plan.UseEvents,
UseDirectory = plan.UseDirectory,
@@ -586,6 +600,7 @@ namespace Bit.Core.Services
MaxCollections = license.MaxCollections,
MaxStorageGb = _globalSettings.SelfHosted ? 10240 : license.MaxStorageGb, // 10 TB
UsePolicies = license.UsePolicies,
+ UseSso = license.UseSso,
UseGroups = license.UseGroups,
UseDirectory = license.UseDirectory,
UseEvents = license.UseEvents,
@@ -747,6 +762,16 @@ namespace Bit.Core.Services
$"policies. Your new license does not allow for the use of policies. Disable all policies.");
}
}
+
+ if (!license.UseSso && organization.UseSso)
+ {
+ var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(organization.Id);
+ if (ssoConfig != null && ssoConfig.Enabled)
+ {
+ throw new BadRequestException($"Your organization currently has a SSO configuration. " +
+ $"Your new license does not allow for the use of SSO. Disable your SSO configuration.");
+ }
+ }
var dir = $"{_globalSettings.LicenseDirectory}/organization";
Directory.CreateDirectory(dir);
@@ -766,6 +791,7 @@ namespace Bit.Core.Services
organization.Use2fa = license.Use2fa;
organization.UseApi = license.UseApi;
organization.UsePolicies = license.UsePolicies;
+ organization.UseSso = license.UseSso;
organization.SelfHost = license.SelfHost;
organization.UsersGetPremium = license.UsersGetPremium;
organization.Plan = license.Plan;
diff --git a/src/Sql/dbo/Stored Procedures/Organization_Create.sql b/src/Sql/dbo/Stored Procedures/Organization_Create.sql
index 78530541a..55394f622 100644
--- a/src/Sql/dbo/Stored Procedures/Organization_Create.sql
+++ b/src/Sql/dbo/Stored Procedures/Organization_Create.sql
@@ -14,6 +14,7 @@
@Seats SMALLINT,
@MaxCollections SMALLINT,
@UsePolicies BIT,
+ @UseSso BIT,
@UseGroups BIT,
@UseDirectory BIT,
@UseEvents BIT,
@@ -56,6 +57,7 @@ BEGIN
[Seats],
[MaxCollections],
[UsePolicies],
+ [UseSso],
[UseGroups],
[UseDirectory],
[UseEvents],
@@ -95,6 +97,7 @@ BEGIN
@Seats,
@MaxCollections,
@UsePolicies,
+ @UseSso,
@UseGroups,
@UseDirectory,
@UseEvents,
diff --git a/src/Sql/dbo/Stored Procedures/Organization_Update.sql b/src/Sql/dbo/Stored Procedures/Organization_Update.sql
index ba3e53bdc..828c5581e 100644
--- a/src/Sql/dbo/Stored Procedures/Organization_Update.sql
+++ b/src/Sql/dbo/Stored Procedures/Organization_Update.sql
@@ -14,6 +14,7 @@
@Seats SMALLINT,
@MaxCollections SMALLINT,
@UsePolicies BIT,
+ @UseSso BIT,
@UseGroups BIT,
@UseDirectory BIT,
@UseEvents BIT,
@@ -56,6 +57,7 @@ BEGIN
[Seats] = @Seats,
[MaxCollections] = @MaxCollections,
[UsePolicies] = @UsePolicies,
+ [UseSso] = @UseSso,
[UseGroups] = @UseGroups,
[UseDirectory] = @UseDirectory,
[UseEvents] = @UseEvents,
diff --git a/src/Sql/dbo/Tables/Organization.sql b/src/Sql/dbo/Tables/Organization.sql
index 8432e8afc..43242f287 100644
--- a/src/Sql/dbo/Tables/Organization.sql
+++ b/src/Sql/dbo/Tables/Organization.sql
@@ -14,6 +14,7 @@
[Seats] SMALLINT NULL,
[MaxCollections] SMALLINT NULL,
[UsePolicies] BIT NOT NULL,
+ [UseSso] BIT NOT NULL,
[UseGroups] BIT NOT NULL,
[UseDirectory] BIT NOT NULL,
[UseEvents] BIT NOT NULL,
diff --git a/src/Sql/dbo/Views/OrganizationUserOrganizationDetailsView.sql b/src/Sql/dbo/Views/OrganizationUserOrganizationDetailsView.sql
index 9afddf910..c6a5ee105 100644
--- a/src/Sql/dbo/Views/OrganizationUserOrganizationDetailsView.sql
+++ b/src/Sql/dbo/Views/OrganizationUserOrganizationDetailsView.sql
@@ -6,6 +6,7 @@ SELECT
O.[Name],
O.[Enabled],
O.[UsePolicies],
+ O.[UseSso],
O.[UseGroups],
O.[UseDirectory],
O.[UseEvents],
diff --git a/test/Core.Test/Services/OrganizationServiceTests.cs b/test/Core.Test/Services/OrganizationServiceTests.cs
index 45ea89092..99ae38369 100644
--- a/test/Core.Test/Services/OrganizationServiceTests.cs
+++ b/test/Core.Test/Services/OrganizationServiceTests.cs
@@ -32,13 +32,14 @@ namespace Bit.Core.Test.Services
var appCacheService = Substitute.For();
var paymentService = Substitute.For();
var policyRepo = Substitute.For();
+ var ssoConfigRepo = Substitute.For();
var referenceEventService = Substitute.For();
var globalSettings = Substitute.For();
var orgService = new OrganizationService(orgRepo, orgUserRepo, collectionRepo, userRepo,
groupRepo, dataProtector, mailService, pushNotService, pushRegService, deviceRepo,
licenseService, eventService, installationRepo, appCacheService, paymentService, policyRepo,
- referenceEventService, globalSettings);
+ ssoConfigRepo, referenceEventService, globalSettings);
var id = Guid.NewGuid();
var userId = Guid.NewGuid();
@@ -91,13 +92,14 @@ namespace Bit.Core.Test.Services
var appCacheService = Substitute.For();
var paymentService = Substitute.For();
var policyRepo = Substitute.For();
+ var ssoConfigRepo = Substitute.For();
var referenceEventService = Substitute.For();
var globalSettings = Substitute.For();
var orgService = new OrganizationService(orgRepo, orgUserRepo, collectionRepo, userRepo,
groupRepo, dataProtector, mailService, pushNotService, pushRegService, deviceRepo,
licenseService, eventService, installationRepo, appCacheService, paymentService, policyRepo,
- referenceEventService, globalSettings);
+ ssoConfigRepo, referenceEventService, globalSettings);
var id = Guid.NewGuid();
var userId = Guid.NewGuid();
diff --git a/util/Migrator/DbScripts/2020-07-20_00_OrgSso.sql b/util/Migrator/DbScripts/2020-07-20_00_OrgSso.sql
new file mode 100644
index 000000000..406b49504
--- /dev/null
+++ b/util/Migrator/DbScripts/2020-07-20_00_OrgSso.sql
@@ -0,0 +1,292 @@
+IF COL_LENGTH('[dbo].[Organization]', 'UseSso') IS NULL
+BEGIN
+ ALTER TABLE
+ [dbo].[Organization]
+ ADD
+ [UseSso] BIT NULL
+END
+GO
+
+UPDATE
+ [dbo].[Organization]
+SET
+ [UseSso] = (CASE WHEN [PlanType] = 10 OR [PlanType] = 11 THEN 1 ELSE 0 END)
+GO
+
+ALTER TABLE
+ [dbo].[Organization]
+ALTER COLUMN
+ [UseSso] BIT NOT NULL
+GO
+
+IF EXISTS(SELECT * FROM sys.views WHERE [Name] = 'OrganizationView')
+BEGIN
+ DROP VIEW [dbo].[OrganizationView]
+END
+GO
+
+CREATE VIEW [dbo].[OrganizationView]
+AS
+SELECT
+ *
+FROM
+ [dbo].[Organization]
+GO
+
+IF EXISTS(SELECT * FROM sys.views WHERE [Name] = 'OrganizationUserOrganizationDetailsView')
+BEGIN
+ DROP VIEW [dbo].[OrganizationUserOrganizationDetailsView]
+END
+GO
+
+CREATE 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.[SelfHost],
+ O.[UsersGetPremium],
+ O.[Seats],
+ O.[MaxCollections],
+ O.[MaxStorageGb],
+ OU.[Key],
+ OU.[Status],
+ OU.[Type]
+FROM
+ [dbo].[OrganizationUser] OU
+INNER JOIN
+ [dbo].[Organization] O ON O.[Id] = OU.[OrganizationId]
+GO
+
+IF OBJECT_ID('[dbo].[Organization_Create]') IS NOT NULL
+BEGIN
+ DROP PROCEDURE [dbo].[Organization_Create]
+END
+GO
+
+CREATE PROCEDURE [dbo].[Organization_Create]
+ @Id UNIQUEIDENTIFIER,
+ @Identifier NVARCHAR(50),
+ @Name NVARCHAR(50),
+ @BusinessName NVARCHAR(50),
+ @BusinessAddress1 NVARCHAR(50),
+ @BusinessAddress2 NVARCHAR(50),
+ @BusinessAddress3 NVARCHAR(50),
+ @BusinessCountry VARCHAR(2),
+ @BusinessTaxNumber NVARCHAR(30),
+ @BillingEmail NVARCHAR(50),
+ @Plan NVARCHAR(50),
+ @PlanType TINYINT,
+ @Seats SMALLINT,
+ @MaxCollections SMALLINT,
+ @UsePolicies BIT,
+ @UseSso BIT,
+ @UseGroups BIT,
+ @UseDirectory BIT,
+ @UseEvents BIT,
+ @UseTotp BIT,
+ @Use2fa BIT,
+ @UseApi BIT,
+ @SelfHost BIT,
+ @UsersGetPremium BIT,
+ @Storage BIGINT,
+ @MaxStorageGb SMALLINT,
+ @Gateway TINYINT,
+ @GatewayCustomerId VARCHAR(50),
+ @GatewaySubscriptionId VARCHAR(50),
+ @ReferenceData VARCHAR(MAX),
+ @Enabled BIT,
+ @LicenseKey VARCHAR(100),
+ @ApiKey VARCHAR(30),
+ @TwoFactorProviders NVARCHAR(MAX),
+ @ExpirationDate DATETIME2(7),
+ @CreationDate DATETIME2(7),
+ @RevisionDate DATETIME2(7)
+AS
+BEGIN
+ SET NOCOUNT ON
+
+ INSERT INTO [dbo].[Organization]
+ (
+ [Id],
+ [Identifier],
+ [Name],
+ [BusinessName],
+ [BusinessAddress1],
+ [BusinessAddress2],
+ [BusinessAddress3],
+ [BusinessCountry],
+ [BusinessTaxNumber],
+ [BillingEmail],
+ [Plan],
+ [PlanType],
+ [Seats],
+ [MaxCollections],
+ [UsePolicies],
+ [UseSso],
+ [UseGroups],
+ [UseDirectory],
+ [UseEvents],
+ [UseTotp],
+ [Use2fa],
+ [UseApi],
+ [SelfHost],
+ [UsersGetPremium],
+ [Storage],
+ [MaxStorageGb],
+ [Gateway],
+ [GatewayCustomerId],
+ [GatewaySubscriptionId],
+ [ReferenceData],
+ [Enabled],
+ [LicenseKey],
+ [ApiKey],
+ [TwoFactorProviders],
+ [ExpirationDate],
+ [CreationDate],
+ [RevisionDate]
+ )
+ VALUES
+ (
+ @Id,
+ @Identifier,
+ @Name,
+ @BusinessName,
+ @BusinessAddress1,
+ @BusinessAddress2,
+ @BusinessAddress3,
+ @BusinessCountry,
+ @BusinessTaxNumber,
+ @BillingEmail,
+ @Plan,
+ @PlanType,
+ @Seats,
+ @MaxCollections,
+ @UsePolicies,
+ @UseSso,
+ @UseGroups,
+ @UseDirectory,
+ @UseEvents,
+ @UseTotp,
+ @Use2fa,
+ @UseApi,
+ @SelfHost,
+ @UsersGetPremium,
+ @Storage,
+ @MaxStorageGb,
+ @Gateway,
+ @GatewayCustomerId,
+ @GatewaySubscriptionId,
+ @ReferenceData,
+ @Enabled,
+ @LicenseKey,
+ @ApiKey,
+ @TwoFactorProviders,
+ @ExpirationDate,
+ @CreationDate,
+ @RevisionDate
+ )
+END
+GO
+
+IF OBJECT_ID('[dbo].[Organization_Update]') IS NOT NULL
+BEGIN
+ DROP PROCEDURE [dbo].[Organization_Update]
+END
+GO
+
+CREATE PROCEDURE [dbo].[Organization_Update]
+ @Id UNIQUEIDENTIFIER,
+ @Identifier NVARCHAR(50),
+ @Name NVARCHAR(50),
+ @BusinessName NVARCHAR(50),
+ @BusinessAddress1 NVARCHAR(50),
+ @BusinessAddress2 NVARCHAR(50),
+ @BusinessAddress3 NVARCHAR(50),
+ @BusinessCountry VARCHAR(2),
+ @BusinessTaxNumber NVARCHAR(30),
+ @BillingEmail NVARCHAR(50),
+ @Plan NVARCHAR(50),
+ @PlanType TINYINT,
+ @Seats SMALLINT,
+ @MaxCollections SMALLINT,
+ @UsePolicies BIT,
+ @UseSso BIT,
+ @UseGroups BIT,
+ @UseDirectory BIT,
+ @UseEvents BIT,
+ @UseTotp BIT,
+ @Use2fa BIT,
+ @UseApi BIT,
+ @SelfHost BIT,
+ @UsersGetPremium BIT,
+ @Storage BIGINT,
+ @MaxStorageGb SMALLINT,
+ @Gateway TINYINT,
+ @GatewayCustomerId VARCHAR(50),
+ @GatewaySubscriptionId VARCHAR(50),
+ @ReferenceData VARCHAR(MAX),
+ @Enabled BIT,
+ @LicenseKey VARCHAR(100),
+ @ApiKey VARCHAR(30),
+ @TwoFactorProviders NVARCHAR(MAX),
+ @ExpirationDate DATETIME2(7),
+ @CreationDate DATETIME2(7),
+ @RevisionDate DATETIME2(7)
+AS
+BEGIN
+ SET NOCOUNT ON
+
+ UPDATE
+ [dbo].[Organization]
+ SET
+ [Identifier] = @Identifier,
+ [Name] = @Name,
+ [BusinessName] = @BusinessName,
+ [BusinessAddress1] = @BusinessAddress1,
+ [BusinessAddress2] = @BusinessAddress2,
+ [BusinessAddress3] = @BusinessAddress3,
+ [BusinessCountry] = @BusinessCountry,
+ [BusinessTaxNumber] = @BusinessTaxNumber,
+ [BillingEmail] = @BillingEmail,
+ [Plan] = @Plan,
+ [PlanType] = @PlanType,
+ [Seats] = @Seats,
+ [MaxCollections] = @MaxCollections,
+ [UsePolicies] = @UsePolicies,
+ [UseSso] = @UseSso,
+ [UseGroups] = @UseGroups,
+ [UseDirectory] = @UseDirectory,
+ [UseEvents] = @UseEvents,
+ [UseTotp] = @UseTotp,
+ [Use2fa] = @Use2fa,
+ [UseApi] = @UseApi,
+ [SelfHost] = @SelfHost,
+ [UsersGetPremium] = @UsersGetPremium,
+ [Storage] = @Storage,
+ [MaxStorageGb] = @MaxStorageGb,
+ [Gateway] = @Gateway,
+ [GatewayCustomerId] = @GatewayCustomerId,
+ [GatewaySubscriptionId] = @GatewaySubscriptionId,
+ [ReferenceData] = @ReferenceData,
+ [Enabled] = @Enabled,
+ [LicenseKey] = @LicenseKey,
+ [ApiKey] = @ApiKey,
+ [TwoFactorProviders] = @TwoFactorProviders,
+ [ExpirationDate] = @ExpirationDate,
+ [CreationDate] = @CreationDate,
+ [RevisionDate] = @RevisionDate
+ WHERE
+ [Id] = @Id
+END
+GO