1
0
mirror of https://github.com/bitwarden/server synced 2026-01-07 11:03:37 +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

@@ -71,6 +71,7 @@ public class OrganizationUsersController : BaseAdminConsoleController
private readonly IFeatureService _featureService;
private readonly IPricingClient _pricingClient;
private readonly IResendOrganizationInviteCommand _resendOrganizationInviteCommand;
private readonly IBulkResendOrganizationInvitesCommand _bulkResendOrganizationInvitesCommand;
private readonly IAutomaticallyConfirmOrganizationUserCommand _automaticallyConfirmOrganizationUserCommand;
private readonly IConfirmOrganizationUserCommand _confirmOrganizationUserCommand;
private readonly IRestoreOrganizationUserCommand _restoreOrganizationUserCommand;
@@ -105,6 +106,7 @@ public class OrganizationUsersController : BaseAdminConsoleController
IInitPendingOrganizationCommand initPendingOrganizationCommand,
IRevokeOrganizationUserCommand revokeOrganizationUserCommand,
IResendOrganizationInviteCommand resendOrganizationInviteCommand,
IBulkResendOrganizationInvitesCommand bulkResendOrganizationInvitesCommand,
IAdminRecoverAccountCommand adminRecoverAccountCommand,
IAutomaticallyConfirmOrganizationUserCommand automaticallyConfirmOrganizationUserCommand)
{
@@ -131,6 +133,7 @@ public class OrganizationUsersController : BaseAdminConsoleController
_featureService = featureService;
_pricingClient = pricingClient;
_resendOrganizationInviteCommand = resendOrganizationInviteCommand;
_bulkResendOrganizationInvitesCommand = bulkResendOrganizationInvitesCommand;
_automaticallyConfirmOrganizationUserCommand = automaticallyConfirmOrganizationUserCommand;
_confirmOrganizationUserCommand = confirmOrganizationUserCommand;
_restoreOrganizationUserCommand = restoreOrganizationUserCommand;
@@ -273,7 +276,17 @@ public class OrganizationUsersController : BaseAdminConsoleController
public async Task<ListResponseModel<OrganizationUserBulkResponseModel>> BulkReinvite(Guid orgId, [FromBody] OrganizationUserBulkRequestModel model)
{
var userId = _userService.GetProperUserId(User);
var result = await _organizationService.ResendInvitesAsync(orgId, userId.Value, model.Ids);
IEnumerable<Tuple<Core.Entities.OrganizationUser, string>> result;
if (_featureService.IsEnabled(FeatureFlagKeys.IncreaseBulkReinviteLimitForCloud))
{
result = await _bulkResendOrganizationInvitesCommand.BulkResendInvitesAsync(orgId, userId.Value, model.Ids);
}
else
{
result = await _organizationService.ResendInvitesAsync(orgId, userId.Value, model.Ids);
}
return new ListResponseModel<OrganizationUserBulkResponseModel>(
result.Select(t => new OrganizationUserBulkResponseModel(t.Item1.Id, t.Item2)));
}