diff --git a/src/Core/Models/Api/Response/ProfileOrganizationResponseModel.cs b/src/Core/Models/Api/Response/ProfileOrganizationResponseModel.cs index 7f829d5ad8..b86e9ce69c 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; UseGroups = organization.UseGroups; + UseDirectory = organization.UseDirectory; Seats = organization.Seats; MaxCollections = organization.MaxCollections; Key = organization.Key; @@ -22,6 +23,7 @@ namespace Bit.Core.Models.Api public string Id { get; set; } public string Name { get; set; } public bool UseGroups { get; set; } + public bool UseDirectory { get; set; } public int Seats { get; set; } public int MaxCollections { get; set; } public string Key { get; set; } diff --git a/src/Core/Models/Data/OrganizationUserOrganizationDetails.cs b/src/Core/Models/Data/OrganizationUserOrganizationDetails.cs index 278eac0ea3..c2651477c2 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 UseGroups { get; set; } + public bool UseDirectory { get; set; } public int Seats { get; set; } public int MaxCollections { get; set; } public string Key { get; set; } diff --git a/src/Core/Models/StaticStore/Plan.cs b/src/Core/Models/StaticStore/Plan.cs index 41fe436728..0a1f79708f 100644 --- a/src/Core/Models/StaticStore/Plan.cs +++ b/src/Core/Models/StaticStore/Plan.cs @@ -12,6 +12,7 @@ namespace Bit.Core.Models.StaticStore public bool CanBuyAdditionalSeats { get; set; } public short? MaxAdditionalSeats { get; set; } public bool UseGroups { get; set; } + public bool UseDirectory { get; set; } public decimal BasePrice { get; set; } public decimal SeatPrice { get; set; } public short? MaxCollections { get; set; } diff --git a/src/Core/Models/Table/Organization.cs b/src/Core/Models/Table/Organization.cs index b5da58e728..6931bd021b 100644 --- a/src/Core/Models/Table/Organization.cs +++ b/src/Core/Models/Table/Organization.cs @@ -15,6 +15,7 @@ namespace Bit.Core.Models.Table public short? Seats { get; set; } public short? MaxCollections { get; set; } public bool UseGroups { get; set; } + public bool UseDirectory { get; set; } public string StripeCustomerId { get; set; } public string StripeSubscriptionId { get; set; } public bool Enabled { get; set; } = true; diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs index 68189d9ce1..fc50db2ef5 100644 --- a/src/Core/Services/Implementations/OrganizationService.cs +++ b/src/Core/Services/Implementations/OrganizationService.cs @@ -576,9 +576,11 @@ namespace Bit.Core.Services Seats = (short)(plan.BaseSeats + signup.AdditionalSeats), MaxCollections = plan.MaxCollections, UseGroups = plan.UseGroups, + UseDirectory = plan.UseDirectory, Plan = plan.Name, StripeCustomerId = customer?.Id, StripeSubscriptionId = subscription?.Id, + Enabled = true, CreationDate = DateTime.UtcNow, RevisionDate = DateTime.UtcNow }; @@ -939,19 +941,19 @@ namespace Bit.Core.Services throw new NotFoundException(); } - if(!organization.UseGroups) + if(!organization.UseDirectory) { - throw new BadRequestException("Organization cannot use groups."); + throw new BadRequestException("Organization cannot use directory syncing."); } - var newUsersSet = new HashSet(newUsers.Select(u => u.ExternalId)); + var newUsersSet = new HashSet(newUsers?.Select(u => u.ExternalId) ?? new List()); var existingUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(organizationId); var existingExternalUsers = existingUsers.Where(u => !string.IsNullOrWhiteSpace(u.ExternalId)).ToList(); var existingExternalUsersIdDict = existingExternalUsers.ToDictionary(u => u.ExternalId, u => u.Id); // Users // Remove Users - if(removeUserExternalIds.Any()) + if(removeUserExternalIds?.Any() ?? false) { var removeUsersSet = new HashSet(removeUserExternalIds); var existingUsersDict = existingExternalUsers.ToDictionary(u => u.ExternalId); @@ -969,7 +971,7 @@ namespace Bit.Core.Services } // Add new users - if(newUsers.Any()) + if(newUsers?.Any() ?? false) { var existingUsersSet = new HashSet(existingExternalUsers.Select(u => u.ExternalId)); var usersToAdd = newUsersSet.Except(existingUsersSet).ToList(); @@ -1026,6 +1028,11 @@ namespace Bit.Core.Services // Groups if(groups?.Any() ?? false) { + if(!organization.UseGroups) + { + throw new BadRequestException("Organization cannot use groups."); + } + var groupsDict = groups.ToDictionary(g => g.Group.ExternalId); var existingGroups = await _groupRepository.GetManyByOrganizationIdAsync(organizationId); var existingExternalGroups = existingGroups.Where(u => !string.IsNullOrWhiteSpace(u.ExternalId)).ToList(); diff --git a/src/Core/Utilities/StaticStore.cs b/src/Core/Utilities/StaticStore.cs index 38a5850bc1..1487e2c103 100644 --- a/src/Core/Utilities/StaticStore.cs +++ b/src/Core/Utilities/StaticStore.cs @@ -152,7 +152,8 @@ namespace Bit.Core.Utilities StripeSeatPlanId = "enterprise-org-seat-monthly", UpgradeSortOrder = 3, TrialPeriodDays = 7, - UseGroups = true + UseGroups = true, + UseDirectory = true }, new Plan { @@ -166,7 +167,8 @@ namespace Bit.Core.Utilities StripeSeatPlanId = "enterprise-org-seat-annually", UpgradeSortOrder = 3, TrialPeriodDays = 7, - UseGroups = true + UseGroups = true, + UseDirectory = true } }; diff --git a/src/Sql/dbo/Stored Procedures/Organization_Create.sql b/src/Sql/dbo/Stored Procedures/Organization_Create.sql index 52725a47a2..a4694b76ad 100644 --- a/src/Sql/dbo/Stored Procedures/Organization_Create.sql +++ b/src/Sql/dbo/Stored Procedures/Organization_Create.sql @@ -8,6 +8,7 @@ @Seats SMALLINT, @MaxCollections SMALLINT, @UseGroups BIT, + @UseDirectory BIT, @StripeCustomerId VARCHAR(50), @StripeSubscriptionId VARCHAR(50), @Enabled BIT, @@ -28,6 +29,7 @@ BEGIN [Seats], [MaxCollections], [UseGroups], + [UseDirectory], [StripeCustomerId], [StripeSubscriptionId], [Enabled], @@ -45,6 +47,7 @@ BEGIN @Seats, @MaxCollections, @UseGroups, + @UseDirectory, @StripeCustomerId, @StripeSubscriptionId, @Enabled, diff --git a/src/Sql/dbo/Stored Procedures/Organization_Update.sql b/src/Sql/dbo/Stored Procedures/Organization_Update.sql index 099e1cd467..ef791011de 100644 --- a/src/Sql/dbo/Stored Procedures/Organization_Update.sql +++ b/src/Sql/dbo/Stored Procedures/Organization_Update.sql @@ -8,6 +8,7 @@ @Seats SMALLINT, @MaxCollections SMALLINT, @UseGroups BIT, + @UseDirectory BIT, @StripeCustomerId VARCHAR(50), @StripeSubscriptionId VARCHAR(50), @Enabled BIT, @@ -29,6 +30,7 @@ BEGIN [Seats] = @Seats, [MaxCollections] = @MaxCollections, [UseGroups] = @UseGroups, + [UseDirectory] = @UseDirectory, [StripeCustomerId] = @StripeCustomerId, [StripeSubscriptionId] = @StripeSubscriptionId, [Enabled] = @Enabled, diff --git a/src/Sql/dbo/Tables/Organization.sql b/src/Sql/dbo/Tables/Organization.sql index 860d3f25d2..254ca99e98 100644 --- a/src/Sql/dbo/Tables/Organization.sql +++ b/src/Sql/dbo/Tables/Organization.sql @@ -8,6 +8,7 @@ [Seats] SMALLINT NULL, [MaxCollections] SMALLINT NULL, [UseGroups] BIT NOT NULL, + [UseDirectory] BIT NOT NULL, [StripeCustomerId] VARCHAR (50) NULL, [StripeSubscriptionId] VARCHAR (50) NULL, [Enabled] BIT NOT NULL, diff --git a/src/Sql/dbo/Views/OrganizationUserOrganizationDetailsView.sql b/src/Sql/dbo/Views/OrganizationUserOrganizationDetailsView.sql index 1f064addc2..e304244c11 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.[UseGroups], + O.[UseDirectory], O.[Seats], O.[MaxCollections], OU.[Key],