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