1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 07:36:14 -05:00

[AC-1568] Finish refactor of update subscription interface, minor fixes (#3189)

* Remove UpdateSecretsManagerSubscriptionCommand.AdjustServiceAccounts interface

* Rewrite tests and use autofixture customizations

* Reduce method nesting in the command, simplify parameters

* Fix capitalization and wording of error messages

* Add checks for existing SM beta enrolment etc
This commit is contained in:
Thomas Rittson
2023-08-28 08:05:23 +10:00
committed by GitHub
parent 4c77f993e5
commit 4748b5b3fc
12 changed files with 190 additions and 182 deletions

View File

@ -5,6 +5,7 @@ using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
using Bit.Core.Repositories;
using Bit.Core.SecretsManager.Commands.AccessTokens.Interfaces;
@ -106,7 +107,7 @@ public class ServiceAccountsControllerTests
.CreateAsync(Arg.Is<ServiceAccount>(sa => sa.Name == data.Name), Arg.Any<Guid>());
await sutProvider.GetDependency<IUpdateSecretsManagerSubscriptionCommand>().DidNotReceiveWithAnyArgs()
.AdjustServiceAccountsAsync(Arg.Any<Organization>(), Arg.Any<int>());
.UpdateSubscriptionAsync(Arg.Any<SecretsManagerSubscriptionUpdate>());
}
[Theory]
@ -124,7 +125,12 @@ public class ServiceAccountsControllerTests
.CreateAsync(Arg.Is<ServiceAccount>(sa => sa.Name == data.Name), Arg.Any<Guid>());
await sutProvider.GetDependency<IUpdateSecretsManagerSubscriptionCommand>().Received(1)
.AdjustServiceAccountsAsync(Arg.Is(organization), Arg.Is(newSlotsRequired));
.UpdateSubscriptionAsync(Arg.Is<SecretsManagerSubscriptionUpdate>(update =>
update.Autoscaling == true &&
update.SmServiceAccounts == organization.SmServiceAccounts + newSlotsRequired &&
!update.SmSeatsChanged &&
!update.MaxAutoscaleSmSeatsChanged &&
!update.MaxAutoscaleSmServiceAccountsChanged));
}
[Theory]

View File

@ -137,6 +137,7 @@ public class SecretsManagerOrganizationCustomization : ICustomization
fixture.Customize<Organization>(composer => composer
.With(o => o.Id, organizationId)
.With(o => o.UseSecretsManager, true)
.With(o => o.SecretsManagerBeta, false)
.With(o => o.PlanType, planType)
.With(o => o.Plan, StaticStore.GetPasswordManagerPlan(planType).Name)
.With(o => o.MaxAutoscaleSmSeats, (int?)null)

View File

@ -95,6 +95,38 @@ public class AddSecretsManagerSubscriptionCommandTests
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task SignUpAsync_ThrowsException_WhenOrganizationEnrolledInSmBeta(
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
Organization organization)
{
organization.UseSecretsManager = true;
organization.SecretsManagerBeta = true;
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.SignUpAsync(organization, 10, 10));
Assert.Contains("Organization is enrolled in Secrets Manager Beta", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task SignUpAsync_ThrowsException_WhenOrganizationAlreadyHasSecretsManager(
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
Organization organization)
{
organization.UseSecretsManager = true;
organization.SecretsManagerBeta = false;
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.SignUpAsync(organization, 10, 10));
Assert.Contains("Organization already uses Secrets Manager", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
private static async Task VerifyDependencyNotCalledAsync(SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider)
{
await sutProvider.GetDependency<IPaymentService>().DidNotReceive()

View File

@ -125,8 +125,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
var update = new SecretsManagerSubscriptionUpdate(organization, autoscaling);
update.AdjustSeats(2);
var update = new SecretsManagerSubscriptionUpdate(organization, autoscaling).AdjustSeats(2);
sutProvider.GetDependency<IGlobalSettings>().SelfHosted.Returns(true);
@ -151,6 +150,23 @@ public class UpdateSecretsManagerSubscriptionCommandTests
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task UpdateSubscriptionAsync_OrganizationEnrolledInSmBeta_ThrowsException(
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider,
Organization organization)
{
organization.UseSecretsManager = true;
organization.SecretsManagerBeta = true;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Organization is enrolled in Secrets Manager Beta", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData(PlanType.EnterpriseAnnually)]
[BitAutoData(PlanType.EnterpriseMonthly)]
@ -163,8 +179,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
{
organization.PlanType = planType;
organization.GatewayCustomerId = null;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustSeats(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustSeats(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("No payment method found.", exception.Message);
@ -183,8 +198,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
{
organization.PlanType = planType;
organization.GatewaySubscriptionId = null;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustSeats(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustSeats(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("No subscription found.", exception.Message);
@ -223,8 +237,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
var expectedSmServiceAccounts = organizationServiceAccounts + smServiceAccountsAdjustment;
var expectedSmServiceAccountsExcludingBase = expectedSmServiceAccounts - plan.BaseServiceAccount.GetValueOrDefault();
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustServiceAccounts(10);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustServiceAccounts(10);
await sutProvider.Sut.UpdateSubscriptionAsync(update);
@ -247,7 +260,6 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.SmSeats = 9;
var update = new SecretsManagerSubscriptionUpdate(organization, false)
{
SmSeats = 10,
@ -267,8 +279,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.SmSeats = null;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustSeats(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustSeats(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.UpdateSubscriptionAsync(update));
@ -283,8 +294,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
var update = new SecretsManagerSubscriptionUpdate(organization, true);
update.AdjustSeats(-2);
var update = new SecretsManagerSubscriptionUpdate(organization, true).AdjustSeats(-2);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Cannot use autoscaling to subtract seats.", exception.Message);
@ -299,8 +309,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.PlanType = planType;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustSeats(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustSeats(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("You have reached the maximum number of Secrets Manager seats (2) for this plan",
@ -317,8 +326,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
organization.SmSeats = 9;
organization.MaxAutoscaleSmSeats = 10;
var update = new SecretsManagerSubscriptionUpdate(organization, true);
update.AdjustSeats(2);
var update = new SecretsManagerSubscriptionUpdate(organization, true).AdjustSeats(2);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Secrets Manager seat limit has been reached.", exception.Message);
@ -375,7 +383,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
sutProvider.GetDependency<IOrganizationUserRepository>().GetOccupiedSmSeatCountByOrganizationIdAsync(organization.Id).Returns(8);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Your organization currently has 8 Secrets Manager seats. Your plan only allows 7 Secrets Manager seats. Remove some Secrets Manager users", exception.Message);
Assert.Contains("8 users are currently occupying Secrets Manager seats. You cannot decrease your subscription below your current occupied seat count", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
@ -385,7 +393,6 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.SmServiceAccounts = 250;
var update = new SecretsManagerSubscriptionUpdate(organization, false)
{
SmServiceAccounts = 300,
@ -405,11 +412,10 @@ public class UpdateSecretsManagerSubscriptionCommandTests
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.SmServiceAccounts = null;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustServiceAccounts(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustServiceAccounts(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Organization has no Service Accounts limit, no need to adjust Service Accounts", exception.Message);
Assert.Contains("Organization has no service accounts limit, no need to adjust service accounts", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
@ -419,8 +425,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
var update = new SecretsManagerSubscriptionUpdate(organization, true);
update.AdjustServiceAccounts(-2);
var update = new SecretsManagerSubscriptionUpdate(organization, true).AdjustServiceAccounts(-2);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Cannot use autoscaling to subtract service accounts.", exception.Message);
@ -435,8 +440,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.PlanType = planType;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustServiceAccounts(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustServiceAccounts(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("You have reached the maximum number of service accounts (3) for this plan",
@ -453,8 +457,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
organization.SmServiceAccounts = 9;
organization.MaxAutoscaleSmServiceAccounts = 10;
var update = new SecretsManagerSubscriptionUpdate(organization, true);
update.AdjustServiceAccounts(2);
var update = new SecretsManagerSubscriptionUpdate(organization, true).AdjustServiceAccounts(2);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Secrets Manager service account limit has been reached.", exception.Message);
@ -492,7 +495,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Plan has a minimum of 200 Service Accounts", exception.Message);
Assert.Contains("Plan has a minimum of 200 service accounts", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
@ -516,7 +519,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
.Returns(currentServiceAccounts);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Your organization currently has 301 Service Accounts. Your plan only allows 201 Service Accounts. Remove some Service Accounts", exception.Message);
Assert.Contains("Your organization currently has 301 service accounts. You cannot decrease your subscription below your current service account usage", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
@ -588,7 +591,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
var update = new SecretsManagerSubscriptionUpdate(organization, false) { MaxAutoscaleSmServiceAccounts = 3 };
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Your plan does not allow Service Accounts autoscaling.", exception.Message);
Assert.Contains("Your plan does not allow service accounts autoscaling.", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}