1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-28 13:15:12 +01:00

[AC-1828] [AC-1807] Aggregated admin panel pricing fixes (#3448)

* AC-1828: Allow reseller to add all teams and enterprise orgs

* AC-1807: Only show provider-eligible plans on Organization edit

* Thomas' feedback

* Matt's feedback
This commit is contained in:
Alex Morask 2023-11-17 15:12:49 -05:00 committed by GitHub
parent b2a3ac4633
commit cf38ff3c19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 8 deletions

View File

@ -82,7 +82,11 @@
<label asp-for="PlanType"></label> <label asp-for="PlanType"></label>
@{ @{
var planTypes = Enum.GetValues<PlanType>() var planTypes = Enum.GetValues<PlanType>()
.Where(p => Model.Provider == null || p is >= PlanType.TeamsMonthly and <= PlanType.TeamsStarter) .Where(p =>
Model.Provider == null ||
(Model.Provider != null
&& p is >= PlanType.TeamsMonthly2019 and <= PlanType.EnterpriseAnnually2019 or >= PlanType.TeamsMonthly2020 and <= PlanType.EnterpriseAnnually)
)
.Select(e => new SelectListItem .Select(e => new SelectListItem
{ {
Value = ((int)e).ToString(), Value = ((int)e).ToString(),

View File

@ -96,9 +96,14 @@ public class OrganizationRepository : Repository<Core.Entities.Organization, Org
public async Task<ICollection<Core.Entities.Organization>> SearchUnassignedToProviderAsync(string name, string ownerEmail, int skip, int take) public async Task<ICollection<Core.Entities.Organization>> SearchUnassignedToProviderAsync(string name, string ownerEmail, int skip, int take)
{ {
using var scope = ServiceScopeFactory.CreateScope(); using var scope = ServiceScopeFactory.CreateScope();
var dbContext = GetDatabaseContext(scope); var dbContext = GetDatabaseContext(scope);
var query = from o in dbContext.Organizations
where o.PlanType >= PlanType.TeamsMonthly2020 && o.PlanType <= PlanType.EnterpriseAnnually && var query =
from o in dbContext.Organizations
where
((o.PlanType >= PlanType.TeamsMonthly2019 && o.PlanType <= PlanType.EnterpriseAnnually2019) ||
(o.PlanType >= PlanType.TeamsMonthly2020 && o.PlanType <= PlanType.EnterpriseAnnually)) &&
!dbContext.ProviderOrganizations.Any(po => po.OrganizationId == o.Id) && !dbContext.ProviderOrganizations.Any(po => po.OrganizationId == o.Id) &&
(string.IsNullOrWhiteSpace(name) || EF.Functions.Like(o.Name, $"%{name}%")) (string.IsNullOrWhiteSpace(name) || EF.Functions.Like(o.Name, $"%{name}%"))
select o; select o;

View File

@ -21,7 +21,7 @@ BEGIN
INNER JOIN INNER JOIN
[dbo].[User] U ON U.[Id] = OU.[UserId] [dbo].[User] U ON U.[Id] = OU.[UserId]
WHERE WHERE
O.[PlanType] >= 8 AND O.[PlanType] <= 11 -- Get 'Team' and 'Enterprise' Organizations ((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations
AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id]) AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id])
AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch) AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch)
AND (U.[Email] LIKE @OwnerLikeSearch) AND (U.[Email] LIKE @OwnerLikeSearch)
@ -36,7 +36,7 @@ BEGIN
FROM FROM
[dbo].[OrganizationView] O [dbo].[OrganizationView] O
WHERE WHERE
O.[PlanType] >= 8 AND O.[PlanType] <= 11 -- Get 'Team' and 'Enterprise' Organizations ((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations
AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id]) AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id])
AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch) AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch)
ORDER BY O.[CreationDate] DESC ORDER BY O.[CreationDate] DESC

View File

@ -0,0 +1,64 @@
/*
This procedure is used by the Bitwarden Admin Panel to retrieve the
Organizations a Reseller Provider is capable of adding as a client.
Currently, the procedure is only surfacing Organizations with the most
current Enterprise or Teams plans, but we actually need to surface any
Enterprise or Teams plan regardless of the version as all of them are
applicable to Resellers.
*/
-- Drop existing SPROC
IF OBJECT_ID('[dbo].[Organization_UnassignedToProviderSearch]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[Organization_UnassignedToProviderSearch]
END
GO
CREATE PROCEDURE [dbo].[Organization_UnassignedToProviderSearch]
@Name NVARCHAR(50),
@OwnerEmail NVARCHAR(256),
@Skip INT = 0,
@Take INT = 25
WITH RECOMPILE
AS
BEGIN
SET NOCOUNT ON
DECLARE @NameLikeSearch NVARCHAR(55) = '%' + @Name + '%'
DECLARE @OwnerLikeSearch NVARCHAR(55) = @OwnerEmail + '%'
IF @OwnerEmail IS NOT NULL
BEGIN
SELECT
O.*
FROM
[dbo].[OrganizationView] O
INNER JOIN
[dbo].[OrganizationUser] OU ON O.[Id] = OU.[OrganizationId]
INNER JOIN
[dbo].[User] U ON U.[Id] = OU.[UserId]
WHERE
((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations
AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id])
AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch)
AND (U.[Email] LIKE @OwnerLikeSearch)
ORDER BY O.[CreationDate] DESC
OFFSET @Skip ROWS
FETCH NEXT @Take ROWS ONLY
END
ELSE
BEGIN
SELECT
O.*
FROM
[dbo].[OrganizationView] O
WHERE
((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations
AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id])
AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch)
ORDER BY O.[CreationDate] DESC
OFFSET @Skip ROWS
FETCH NEXT @Take ROWS ONLY
END
END
GO