mirror of
https://github.com/bitwarden/server.git
synced 2025-05-03 10:42:21 -05:00
Added integration test around enabling feature and sending invite via scim. Did a bit of refactoring on the SM validation. Fixed couple bugs found.
This commit is contained in:
parent
bd5189491e
commit
001a5dea86
@ -1,9 +1,12 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Scim.IntegrationTest.Factories;
|
||||
using Bit.Scim.Models;
|
||||
using Bit.Scim.Utilities;
|
||||
using Bit.Test.Common.Helpers;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Scim.IntegrationTest.Controllers.v2;
|
||||
@ -276,9 +279,15 @@ public class UsersControllerTests : IClassFixture<ScimApplicationFactory>, IAsyn
|
||||
AssertHelper.AssertPropertyEqual(expectedResponse, responseModel);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Post_Success()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public async Task Post_Success(bool isScimInviteUserOptimizationEnabled)
|
||||
{
|
||||
_factory.SubstituteService((IFeatureService featureService)
|
||||
=> featureService.IsEnabled(FeatureFlagKeys.ScimInviteUserOptimization)
|
||||
.Returns(isScimInviteUserOptimizationEnabled));
|
||||
|
||||
var email = "user5@example.com";
|
||||
var displayName = "Test User 5";
|
||||
var externalId = "UE";
|
||||
|
@ -96,7 +96,8 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
|
||||
var valid = validationResult as Valid<InviteUserOrganizationValidationRequest>;
|
||||
|
||||
var organizationUserCollection = invitesToSend
|
||||
.Select(MapToDataModel(request.PerformedAt));
|
||||
.Select(MapToDataModel(request.PerformedAt))
|
||||
.ToArray();
|
||||
|
||||
var organization = await organizationRepository.GetByIdAsync(valid.Value.Organization.OrganizationId);
|
||||
try
|
||||
|
@ -5,6 +5,20 @@ namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUse
|
||||
|
||||
public class InviteUserOrganizationValidationRequest
|
||||
{
|
||||
public InviteUserOrganizationValidationRequest() { }
|
||||
|
||||
public InviteUserOrganizationValidationRequest(InviteUserOrganizationValidationRequest request, PasswordManagerSubscriptionUpdate subscriptionUpdate, SecretsManagerSubscriptionUpdate smSubscriptionUpdate)
|
||||
{
|
||||
Invites = request.Invites;
|
||||
Organization = request.Organization;
|
||||
PerformedBy = request.PerformedBy;
|
||||
PerformedAt = request.PerformedAt;
|
||||
OccupiedPmSeats = request.OccupiedPmSeats;
|
||||
OccupiedSmSeats = request.OccupiedSmSeats;
|
||||
PasswordManagerSubscriptionUpdate = subscriptionUpdate;
|
||||
SecretsManagerSubscriptionUpdate = smSubscriptionUpdate;
|
||||
}
|
||||
|
||||
public OrganizationUserInviteDto[] Invites { get; init; } = [];
|
||||
public OrganizationDto Organization { get; init; }
|
||||
public Guid PerformedBy { get; init; }
|
||||
|
@ -51,7 +51,8 @@ public class InviteUsersValidation(
|
||||
|
||||
var provider = await providerRepository.GetByOrganizationIdAsync(request.Organization.OrganizationId);
|
||||
|
||||
if (InvitingUserOrganizationProviderValidation.Validate(ProviderDto.FromProviderEntity(provider)) is
|
||||
if (provider is not null &&
|
||||
InvitingUserOrganizationProviderValidation.Validate(ProviderDto.FromProviderEntity(provider)) is
|
||||
Invalid<ProviderDto> invalidProviderValidation)
|
||||
{
|
||||
return new Invalid<InviteUserOrganizationValidationRequest>(invalidProviderValidation.ErrorMessageString);
|
||||
@ -65,7 +66,10 @@ public class InviteUsersValidation(
|
||||
return new Invalid<InviteUserOrganizationValidationRequest>(invalidPaymentValidation.ErrorMessageString);
|
||||
}
|
||||
|
||||
return new Valid<InviteUserOrganizationValidationRequest>(null);
|
||||
return new Valid<InviteUserOrganizationValidationRequest>(new InviteUserOrganizationValidationRequest(
|
||||
request,
|
||||
subscriptionUpdate,
|
||||
smSubscriptionUpdate));
|
||||
}
|
||||
|
||||
public static ValidationResult<IGlobalSettings> ValidateEnvironment(IGlobalSettings globalSettings) =>
|
||||
|
@ -7,6 +7,11 @@ public static class InvitingUserOrganizationValidation
|
||||
{
|
||||
public static ValidationResult<OrganizationDto> Validate(OrganizationDto organization)
|
||||
{
|
||||
if (organization.Seats is null)
|
||||
{
|
||||
return new Valid<OrganizationDto>(organization);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(organization.GatewayCustomerId))
|
||||
{
|
||||
return new Invalid<OrganizationDto>(NoPaymentMethodFoundError);
|
||||
|
@ -5,41 +5,39 @@ namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUse
|
||||
|
||||
public static class SecretsManagerInviteUserValidation
|
||||
{
|
||||
// NOTE This is only validating adding new users
|
||||
public static ValidationResult<SecretsManagerSubscriptionUpdate> Validate(SecretsManagerSubscriptionUpdate subscriptionUpdate)
|
||||
{
|
||||
if (subscriptionUpdate.UseSecretsManger is false)
|
||||
public static ValidationResult<SecretsManagerSubscriptionUpdate> Validate(
|
||||
SecretsManagerSubscriptionUpdate subscriptionUpdate) =>
|
||||
subscriptionUpdate switch
|
||||
{
|
||||
return new Invalid<SecretsManagerSubscriptionUpdate>(OrganizationNoSecretsManager);
|
||||
}
|
||||
{ UseSecretsManger: false, AdditionalSeats: > 0 } =>
|
||||
new Invalid<SecretsManagerSubscriptionUpdate>(OrganizationNoSecretsManager),
|
||||
|
||||
if (subscriptionUpdate.Seats == null)
|
||||
{
|
||||
return new Valid<SecretsManagerSubscriptionUpdate>(subscriptionUpdate); // no need to adjust seats...continue on
|
||||
}
|
||||
{ UseSecretsManger: false, AdditionalSeats: 0 } or { UseSecretsManger: true, Seats: null } =>
|
||||
new Valid<SecretsManagerSubscriptionUpdate>(subscriptionUpdate),
|
||||
|
||||
// max additional seats is never set...maybe remove this
|
||||
if (subscriptionUpdate.SecretsManagerPlan is { HasAdditionalSeatsOption: false } ||
|
||||
subscriptionUpdate.SecretsManagerPlan.MaxAdditionalSeats is not null &&
|
||||
subscriptionUpdate.AdditionalSeats > subscriptionUpdate.SecretsManagerPlan.MaxAdditionalSeats)
|
||||
{
|
||||
return new Invalid<SecretsManagerSubscriptionUpdate>(
|
||||
string.Format(SecretsManagerAdditionalSeatLimitReached,
|
||||
{ UseSecretsManger: true, SecretsManagerPlan.HasAdditionalSeatsOption: false } =>
|
||||
new Invalid<SecretsManagerSubscriptionUpdate>(
|
||||
string.Format(SecretsManagerAdditionalSeatLimitReached,
|
||||
subscriptionUpdate.SecretsManagerPlan.BaseSeats +
|
||||
subscriptionUpdate.SecretsManagerPlan.MaxAdditionalSeats.GetValueOrDefault()));
|
||||
}
|
||||
subscriptionUpdate.SecretsManagerPlan.MaxAdditionalSeats.GetValueOrDefault())),
|
||||
|
||||
if (subscriptionUpdate.UpdatedSeatTotal is not null && subscriptionUpdate.MaxAutoScaleSeats is not null &&
|
||||
subscriptionUpdate.UpdatedSeatTotal > subscriptionUpdate.MaxAutoScaleSeats)
|
||||
{
|
||||
return new Invalid<SecretsManagerSubscriptionUpdate>(SecretsManagerSeatLimitReached);
|
||||
}
|
||||
{ UseSecretsManger: true, SecretsManagerPlan.MaxAdditionalSeats: var planMaxSeats }
|
||||
when planMaxSeats < subscriptionUpdate.AdditionalSeats =>
|
||||
new Invalid<SecretsManagerSubscriptionUpdate>(
|
||||
string.Format(SecretsManagerAdditionalSeatLimitReached,
|
||||
subscriptionUpdate.SecretsManagerPlan.BaseSeats +
|
||||
subscriptionUpdate.SecretsManagerPlan.MaxAdditionalSeats.GetValueOrDefault())),
|
||||
|
||||
if (subscriptionUpdate.PasswordManagerUpdatedSeatTotal < subscriptionUpdate.UpdatedSeatTotal)
|
||||
{
|
||||
return new Invalid<SecretsManagerSubscriptionUpdate>(SecretsManagerCannotExceedPasswordManager);
|
||||
}
|
||||
{ UseSecretsManger: true, UpdatedSeatTotal: var updateSeatTotal, MaxAutoScaleSeats: var maxAutoScaleSeats }
|
||||
when updateSeatTotal > maxAutoScaleSeats =>
|
||||
new Invalid<SecretsManagerSubscriptionUpdate>(SecretsManagerSeatLimitReached),
|
||||
|
||||
return new Valid<SecretsManagerSubscriptionUpdate>(subscriptionUpdate);
|
||||
}
|
||||
{
|
||||
PasswordManagerUpdatedSeatTotal: var passwordManagerUpdatedSeatTotal,
|
||||
UpdatedSeatTotal: var secretsManagerUpdatedSeatTotal
|
||||
} when passwordManagerUpdatedSeatTotal < secretsManagerUpdatedSeatTotal =>
|
||||
new Invalid<SecretsManagerSubscriptionUpdate>(SecretsManagerCannotExceedPasswordManager),
|
||||
|
||||
_ => new Valid<SecretsManagerSubscriptionUpdate>(subscriptionUpdate)
|
||||
};
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class SecretsManagerInviteUserValidationTests
|
||||
{
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void Validate_GivenOrganizationDoesNotHaveSecretsManager_ThenShouldNotBeAllowedToAddSecretsManagerUsers(
|
||||
public void Validate_GivenOrganizationDoesNotHaveSecretsManagerAndNotTryingToAddSecretsManagerUser_ThenTheRequestIsValid(
|
||||
Organization organization)
|
||||
{
|
||||
organization.UseSecretsManager = false;
|
||||
@ -38,6 +38,35 @@ public class SecretsManagerInviteUserValidationTests
|
||||
|
||||
var result = SecretsManagerInviteUserValidation.Validate(update);
|
||||
|
||||
Assert.IsType<Valid<SecretsManagerSubscriptionUpdate>>(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void Validate_GivenOrganizationDoesNotHaveSecretsManagerAndTryingToAddSecretsManagerUser_ThenShouldReturnInvalidMessage(
|
||||
Organization organization)
|
||||
{
|
||||
organization.UseSecretsManager = false;
|
||||
|
||||
var organizationDto = OrganizationDto.FromOrganization(organization);
|
||||
var subscriptionUpdate = PasswordManagerSubscriptionUpdate.Create(organizationDto, 0, 0);
|
||||
|
||||
var invite = OrganizationUserInvite.Create(["email@test.com"], [], OrganizationUserType.User, new Permissions(), string.Empty, true);
|
||||
|
||||
var request = new InviteUserOrganizationValidationRequest
|
||||
{
|
||||
Invites = [OrganizationUserInviteDto.Create(invite.Emails.First(), invite, organizationDto.OrganizationId)],
|
||||
Organization = organizationDto,
|
||||
PerformedBy = Guid.Empty,
|
||||
PerformedAt = default,
|
||||
OccupiedPmSeats = 0,
|
||||
OccupiedSmSeats = 0
|
||||
};
|
||||
|
||||
var update = SecretsManagerSubscriptionUpdate.Create(request, subscriptionUpdate);
|
||||
|
||||
var result = SecretsManagerInviteUserValidation.Validate(update);
|
||||
|
||||
Assert.IsType<Invalid<SecretsManagerSubscriptionUpdate>>(result);
|
||||
Assert.Equal(InviteUserValidationErrorMessages.OrganizationNoSecretsManager, result.ErrorMessageString);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user