1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-21 12:05:42 +01:00

[AC-2211] SM Changes (#3938)

* SM changes

* Teams starter bugs
This commit is contained in:
Conner Turnbull 2024-04-08 14:42:01 -04:00 committed by GitHub
parent d9658ce3fe
commit 9a2d383417
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 308 additions and 23 deletions

View File

@ -28,14 +28,24 @@ public enum PlanType : byte
EnterpriseMonthly2020 = 10,
[Display(Name = "Enterprise (Annually) 2020")]
EnterpriseAnnually2020 = 11,
[Display(Name = "Teams (Monthly) 2023")]
TeamsMonthly2023 = 12,
[Display(Name = "Teams (Annually) 2023")]
TeamsAnnually2023 = 13,
[Display(Name = "Enterprise (Monthly) 2023")]
EnterpriseMonthly2023 = 14,
[Display(Name = "Enterprise (Annually) 2023")]
EnterpriseAnnually2023 = 15,
[Display(Name = "Teams Starter 2023")]
TeamsStarter2023 = 16,
[Display(Name = "Teams (Monthly)")]
TeamsMonthly = 12,
TeamsMonthly = 17,
[Display(Name = "Teams (Annually)")]
TeamsAnnually = 13,
TeamsAnnually = 18,
[Display(Name = "Enterprise (Monthly)")]
EnterpriseMonthly = 14,
EnterpriseMonthly = 19,
[Display(Name = "Enterprise (Annually)")]
EnterpriseAnnually = 15,
EnterpriseAnnually = 20,
[Display(Name = "Teams Starter")]
TeamsStarter = 16,
TeamsStarter = 21,
}

View File

@ -2,7 +2,7 @@
namespace Bit.Core.Models.StaticStore.Plans;
public record EnterprisePlan : Models.StaticStore.Plan
public record EnterprisePlan : Plan
{
public EnterprisePlan(bool isAnnual)
{
@ -44,7 +44,7 @@ public record EnterprisePlan : Models.StaticStore.Plan
{
BaseSeats = 0;
BasePrice = 0;
BaseServiceAccount = 200;
BaseServiceAccount = 50;
HasAdditionalSeatsOption = true;
HasAdditionalServiceAccountOption = true;
@ -55,16 +55,16 @@ public record EnterprisePlan : Models.StaticStore.Plan
if (isAnnual)
{
StripeSeatPlanId = "secrets-manager-enterprise-seat-annually";
StripeServiceAccountPlanId = "secrets-manager-service-account-annually";
StripeServiceAccountPlanId = "secrets-manager-service-account-2024-annually";
SeatPrice = 144;
AdditionalPricePerServiceAccount = 6;
AdditionalPricePerServiceAccount = 12;
}
else
{
StripeSeatPlanId = "secrets-manager-enterprise-seat-monthly";
StripeServiceAccountPlanId = "secrets-manager-service-account-monthly";
StripeServiceAccountPlanId = "secrets-manager-service-account-2024-monthly";
SeatPrice = 13;
AdditionalPricePerServiceAccount = 0.5M;
AdditionalPricePerServiceAccount = 1;
}
}
}

View File

@ -0,0 +1,102 @@
using Bit.Core.Enums;
namespace Bit.Core.Models.StaticStore.Plans;
public record Enterprise2023Plan : Plan
{
public Enterprise2023Plan(bool isAnnual)
{
Type = isAnnual ? PlanType.EnterpriseAnnually2023 : PlanType.EnterpriseMonthly2023;
Product = ProductType.Enterprise;
Name = isAnnual ? "Enterprise (Annually)" : "Enterprise (Monthly)";
IsAnnual = isAnnual;
NameLocalizationKey = "planNameEnterprise";
DescriptionLocalizationKey = "planDescEnterprise";
CanBeUsedByBusiness = true;
TrialPeriodDays = 7;
HasPolicies = true;
HasSelfHost = true;
HasGroups = true;
HasDirectory = true;
HasEvents = true;
HasTotp = true;
Has2fa = true;
HasApi = true;
HasSso = true;
HasKeyConnector = true;
HasScim = true;
HasResetPassword = true;
UsersGetPremium = true;
HasCustomPermissions = true;
UpgradeSortOrder = 4;
DisplaySortOrder = 4;
LegacyYear = 2024;
PasswordManager = new Enterprise2023PasswordManagerFeatures(isAnnual);
SecretsManager = new Enterprise2023SecretsManagerFeatures(isAnnual);
}
private record Enterprise2023SecretsManagerFeatures : SecretsManagerPlanFeatures
{
public Enterprise2023SecretsManagerFeatures(bool isAnnual)
{
BaseSeats = 0;
BasePrice = 0;
BaseServiceAccount = 200;
HasAdditionalSeatsOption = true;
HasAdditionalServiceAccountOption = true;
AllowSeatAutoscale = true;
AllowServiceAccountsAutoscale = true;
if (isAnnual)
{
StripeSeatPlanId = "secrets-manager-enterprise-seat-annually";
StripeServiceAccountPlanId = "secrets-manager-service-account-annually";
SeatPrice = 144;
AdditionalPricePerServiceAccount = 6;
}
else
{
StripeSeatPlanId = "secrets-manager-enterprise-seat-monthly";
StripeServiceAccountPlanId = "secrets-manager-service-account-monthly";
SeatPrice = 13;
AdditionalPricePerServiceAccount = 0.5M;
}
}
}
private record Enterprise2023PasswordManagerFeatures : PasswordManagerPlanFeatures
{
public Enterprise2023PasswordManagerFeatures(bool isAnnual)
{
BaseSeats = 0;
BaseStorageGb = 1;
HasAdditionalStorageOption = true;
HasAdditionalSeatsOption = true;
AllowSeatAutoscale = true;
if (isAnnual)
{
AdditionalStoragePricePerGb = 4;
StripeStoragePlanId = "storage-gb-annually";
StripeSeatPlanId = "2023-enterprise-org-seat-annually";
SeatPrice = 72;
}
else
{
StripeSeatPlanId = "2023-enterprise-seat-monthly";
StripeStoragePlanId = "storage-gb-monthly";
SeatPrice = 7;
AdditionalStoragePricePerGb = 0.5M;
}
}
}
}

View File

@ -2,7 +2,7 @@
namespace Bit.Core.Models.StaticStore.Plans;
public record TeamsPlan : Models.StaticStore.Plan
public record TeamsPlan : Plan
{
public TeamsPlan(bool isAnnual)
{
@ -37,7 +37,7 @@ public record TeamsPlan : Models.StaticStore.Plan
{
BaseSeats = 0;
BasePrice = 0;
BaseServiceAccount = 50;
BaseServiceAccount = 20;
HasAdditionalSeatsOption = true;
HasAdditionalServiceAccountOption = true;
@ -48,16 +48,16 @@ public record TeamsPlan : Models.StaticStore.Plan
if (isAnnual)
{
StripeSeatPlanId = "secrets-manager-teams-seat-annually";
StripeServiceAccountPlanId = "secrets-manager-service-account-annually";
StripeServiceAccountPlanId = "secrets-manager-service-account-2024-annually";
SeatPrice = 72;
AdditionalPricePerServiceAccount = 6;
AdditionalPricePerServiceAccount = 12;
}
else
{
StripeSeatPlanId = "secrets-manager-teams-seat-monthly";
StripeServiceAccountPlanId = "secrets-manager-service-account-monthly";
StripeServiceAccountPlanId = "secrets-manager-service-account-2024-monthly";
SeatPrice = 7;
AdditionalPricePerServiceAccount = 0.5M;
AdditionalPricePerServiceAccount = 1;
}
}
}

View File

@ -0,0 +1,96 @@
using Bit.Core.Enums;
namespace Bit.Core.Models.StaticStore.Plans;
public record Teams2023Plan : Plan
{
public Teams2023Plan(bool isAnnual)
{
Type = isAnnual ? PlanType.TeamsAnnually2023 : PlanType.TeamsMonthly2023;
Product = ProductType.Teams;
Name = isAnnual ? "Teams (Annually)" : "Teams (Monthly)";
IsAnnual = isAnnual;
NameLocalizationKey = "planNameTeams";
DescriptionLocalizationKey = "planDescTeams";
CanBeUsedByBusiness = true;
TrialPeriodDays = 7;
HasGroups = true;
HasDirectory = true;
HasEvents = true;
HasTotp = true;
Has2fa = true;
HasApi = true;
UsersGetPremium = true;
UpgradeSortOrder = 3;
DisplaySortOrder = 3;
LegacyYear = 2024;
PasswordManager = new Teams2023PasswordManagerFeatures(isAnnual);
SecretsManager = new Teams2023SecretsManagerFeatures(isAnnual);
}
private record Teams2023SecretsManagerFeatures : SecretsManagerPlanFeatures
{
public Teams2023SecretsManagerFeatures(bool isAnnual)
{
BaseSeats = 0;
BasePrice = 0;
BaseServiceAccount = 50;
HasAdditionalSeatsOption = true;
HasAdditionalServiceAccountOption = true;
AllowSeatAutoscale = true;
AllowServiceAccountsAutoscale = true;
if (isAnnual)
{
StripeSeatPlanId = "secrets-manager-teams-seat-annually";
StripeServiceAccountPlanId = "secrets-manager-service-account-annually";
SeatPrice = 72;
AdditionalPricePerServiceAccount = 6;
}
else
{
StripeSeatPlanId = "secrets-manager-teams-seat-monthly";
StripeServiceAccountPlanId = "secrets-manager-service-account-monthly";
SeatPrice = 7;
AdditionalPricePerServiceAccount = 0.5M;
}
}
}
private record Teams2023PasswordManagerFeatures : PasswordManagerPlanFeatures
{
public Teams2023PasswordManagerFeatures(bool isAnnual)
{
BaseSeats = 0;
BaseStorageGb = 1;
BasePrice = 0;
HasAdditionalStorageOption = true;
HasAdditionalSeatsOption = true;
AllowSeatAutoscale = true;
if (isAnnual)
{
StripeStoragePlanId = "storage-gb-annually";
StripeSeatPlanId = "2023-teams-org-seat-annually";
SeatPrice = 48;
AdditionalStoragePricePerGb = 4;
}
else
{
StripeSeatPlanId = "2023-teams-org-seat-monthly";
StripeStoragePlanId = "storage-gb-monthly";
SeatPrice = 5;
AdditionalStoragePricePerGb = 0.5M;
}
}
}
}

View File

@ -36,7 +36,7 @@ public record TeamsStarterPlan : Plan
{
BaseSeats = 0;
BasePrice = 0;
BaseServiceAccount = 50;
BaseServiceAccount = 20;
HasAdditionalSeatsOption = true;
HasAdditionalServiceAccountOption = true;
@ -45,9 +45,9 @@ public record TeamsStarterPlan : Plan
AllowServiceAccountsAutoscale = true;
StripeSeatPlanId = "secrets-manager-teams-seat-monthly";
StripeServiceAccountPlanId = "secrets-manager-service-account-monthly";
StripeServiceAccountPlanId = "secrets-manager-service-account-2024-monthly";
SeatPrice = 7;
AdditionalPricePerServiceAccount = 0.5M;
AdditionalPricePerServiceAccount = 1;
}
}

View File

@ -0,0 +1,72 @@
using Bit.Core.Enums;
namespace Bit.Core.Models.StaticStore.Plans;
public record TeamsStarterPlan2023 : Plan
{
public TeamsStarterPlan2023()
{
Type = PlanType.TeamsStarter2023;
Product = ProductType.TeamsStarter;
Name = "Teams (Starter)";
NameLocalizationKey = "planNameTeamsStarter";
DescriptionLocalizationKey = "planDescTeams";
CanBeUsedByBusiness = true;
TrialPeriodDays = 7;
HasGroups = true;
HasDirectory = true;
HasEvents = true;
HasTotp = true;
Has2fa = true;
HasApi = true;
UsersGetPremium = true;
UpgradeSortOrder = 2;
DisplaySortOrder = 2;
PasswordManager = new TeamsStarter2023PasswordManagerFeatures();
SecretsManager = new TeamsStarter2023SecretsManagerFeatures();
LegacyYear = 2024;
}
private record TeamsStarter2023SecretsManagerFeatures : SecretsManagerPlanFeatures
{
public TeamsStarter2023SecretsManagerFeatures()
{
BaseSeats = 0;
BasePrice = 0;
BaseServiceAccount = 50;
HasAdditionalSeatsOption = true;
HasAdditionalServiceAccountOption = true;
AllowSeatAutoscale = true;
AllowServiceAccountsAutoscale = true;
StripeSeatPlanId = "secrets-manager-teams-seat-monthly";
StripeServiceAccountPlanId = "secrets-manager-service-account-monthly";
SeatPrice = 7;
AdditionalPricePerServiceAccount = 0.5M;
}
}
private record TeamsStarter2023PasswordManagerFeatures : PasswordManagerPlanFeatures
{
public TeamsStarter2023PasswordManagerFeatures()
{
BaseSeats = 10;
BaseStorageGb = 1;
BasePrice = 20;
MaxSeats = 10;
HasAdditionalStorageOption = true;
StripePlanId = "teams-org-starter";
StripeStoragePlanId = "storage-gb-monthly";
AdditionalStoragePricePerGb = 0.5M;
}
}
}

View File

@ -114,8 +114,13 @@ public static class StaticStore
new TeamsPlan(true),
new TeamsPlan(false),
new Enterprise2023Plan(true),
new Enterprise2023Plan(false),
new Enterprise2020Plan(true),
new Enterprise2020Plan(false),
new TeamsStarterPlan2023(),
new Teams2023Plan(true),
new Teams2023Plan(false),
new Teams2020Plan(true),
new Teams2020Plan(false),
new FamiliesPlan(),

View File

@ -526,7 +526,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
const int newSmServiceAccounts = 199;
const int newSmServiceAccounts = 49;
organization.SmServiceAccounts = newSmServiceAccounts - 10;
@ -537,7 +537,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Plan has a minimum of 200 machine accounts", exception.Message);
Assert.Contains("Plan has a minimum of 50 machine accounts", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}

View File

@ -13,7 +13,7 @@ public class StaticStoreTests
var plans = StaticStore.Plans.ToList();
Assert.NotNull(plans);
Assert.NotEmpty(plans);
Assert.Equal(17, plans.Count);
Assert.Equal(22, plans.Count);
}
[Theory]