1
0
mirror of https://github.com/bitwarden/server synced 2025-12-15 15:53:59 +00:00

[PM-28260] Optimize bulk reinvite endpoint (#6670)

* Implement optimized bulk invite resend command

- Added IBulkResendOrganizationInvitesCommand interface to define the bulk resend operation.
- Created BulkResendOrganizationInvitesCommand class to handle the logic for resending invites to multiple organization users.
- Integrated logging and validation to ensure only valid users receive invites.
- Included error handling for non-existent organizations and invalid user statuses.

* Add unit tests for BulkResendOrganizationInvitesCommand

- Implemented comprehensive test cases for the BulkResendOrganizationInvitesCommand class.
- Validated user statuses and ensured correct handling of valid and invalid users during bulk invite resends.
- Included tests for scenarios such as organization not found and empty user lists.
- Utilized Xunit and NSubstitute for effective testing and mocking of dependencies.

* Add IBulkResendOrganizationInvitesCommand to service collection

- Registered IBulkResendOrganizationInvitesCommand in the service collection for dependency injection.

* Update OrganizationUsersController to utilize IBulkResendOrganizationInvitesCommand

- Added IBulkResendOrganizationInvitesCommand to the OrganizationUsersController for handling bulk invite resends based on feature flag.
- Updated BulkReinvite method to conditionally use the new command or the legacy service based on the feature flag status.
- Enhanced unit tests to verify correct command usage depending on feature flag state, ensuring robust testing for both scenarios.
This commit is contained in:
Rui Tomé
2025-12-05 16:28:04 +00:00
committed by GitHub
parent 18a8829476
commit 5469d8be0e
6 changed files with 282 additions and 1 deletions

View File

@@ -11,6 +11,7 @@ using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
using Bit.Core.AdminConsole.OrganizationFeatures.AccountRecovery;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.AutoConfirmUser;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
using Bit.Core.AdminConsole.Repositories;
@@ -730,4 +731,68 @@ public class OrganizationUsersControllerTests
var problemResult = Assert.IsType<JsonHttpResult<ErrorResponseModel>>(result);
Assert.Equal(StatusCodes.Status500InternalServerError, problemResult.StatusCode);
}
[Theory]
[BitAutoData]
public async Task BulkReinvite_WhenFeatureFlagEnabled_UsesBulkResendOrganizationInvitesCommand(
Guid organizationId,
OrganizationUserBulkRequestModel bulkRequestModel,
List<OrganizationUser> organizationUsers,
Guid userId,
SutProvider<OrganizationUsersController> sutProvider)
{
// Arrange
sutProvider.GetDependency<ICurrentContext>().ManageUsers(organizationId).Returns(true);
sutProvider.GetDependency<IUserService>().GetProperUserId(Arg.Any<ClaimsPrincipal>()).Returns(userId);
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.IncreaseBulkReinviteLimitForCloud)
.Returns(true);
var expectedResults = organizationUsers.Select(u => Tuple.Create(u, "")).ToList();
sutProvider.GetDependency<IBulkResendOrganizationInvitesCommand>()
.BulkResendInvitesAsync(organizationId, userId, bulkRequestModel.Ids)
.Returns(expectedResults);
// Act
var response = await sutProvider.Sut.BulkReinvite(organizationId, bulkRequestModel);
// Assert
Assert.Equal(organizationUsers.Count, response.Data.Count());
await sutProvider.GetDependency<IBulkResendOrganizationInvitesCommand>()
.Received(1)
.BulkResendInvitesAsync(organizationId, userId, bulkRequestModel.Ids);
}
[Theory]
[BitAutoData]
public async Task BulkReinvite_WhenFeatureFlagDisabled_UsesLegacyOrganizationService(
Guid organizationId,
OrganizationUserBulkRequestModel bulkRequestModel,
List<OrganizationUser> organizationUsers,
Guid userId,
SutProvider<OrganizationUsersController> sutProvider)
{
// Arrange
sutProvider.GetDependency<ICurrentContext>().ManageUsers(organizationId).Returns(true);
sutProvider.GetDependency<IUserService>().GetProperUserId(Arg.Any<ClaimsPrincipal>()).Returns(userId);
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.IncreaseBulkReinviteLimitForCloud)
.Returns(false);
var expectedResults = organizationUsers.Select(u => Tuple.Create(u, "")).ToList();
sutProvider.GetDependency<IOrganizationService>()
.ResendInvitesAsync(organizationId, userId, bulkRequestModel.Ids)
.Returns(expectedResults);
// Act
var response = await sutProvider.Sut.BulkReinvite(organizationId, bulkRequestModel);
// Assert
Assert.Equal(organizationUsers.Count, response.Data.Count());
await sutProvider.GetDependency<IOrganizationService>()
.Received(1)
.ResendInvitesAsync(organizationId, userId, bulkRequestModel.Ids);
}
}