1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-16 15:53:13 -05:00

[PM-22205] Fix logic for sending out revoked email (#5933)

This commit is contained in:
Jimmy Vo 2025-06-11 16:55:42 -04:00 committed by GitHub
parent be72a77c72
commit 821f66e99f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 8 deletions

View File

@ -104,8 +104,8 @@ public class TwoFactorAuthenticationPolicyValidator : IPolicyValidator
throw new BadRequestException(string.Join(", ", commandResult.ErrorMessages));
}
await Task.WhenAll(currentActiveRevocableOrganizationUsers.Select(x =>
_mailService.SendOrganizationUserRevokedForTwoFactorPolicyEmailAsync(organization.DisplayName(), x.Email)));
await Task.WhenAll(nonCompliantUsers.Select(nonCompliantUser =>
_mailService.SendOrganizationUserRevokedForTwoFactorPolicyEmailAsync(organization.DisplayName(), nonCompliantUser.user.Email)));
}
private static bool MembersWithNoMasterPasswordWillLoseAccess(

View File

@ -60,16 +60,19 @@ public class TwoFactorAuthenticationPolicyValidatorTests
}
[Theory, BitAutoData]
public async Task OnSaveSideEffectsAsync_RevokesNonCompliantUsers(
public async Task OnSaveSideEffectsAsync_RevokesOnlyNonCompliantUsers(
Organization organization,
[PolicyUpdate(PolicyType.TwoFactorAuthentication)] PolicyUpdate policyUpdate,
[Policy(PolicyType.TwoFactorAuthentication, false)] Policy policy,
SutProvider<TwoFactorAuthenticationPolicyValidator> sutProvider)
{
policy.OrganizationId = organization.Id = policyUpdate.OrganizationId;
// Arrange
policy.OrganizationId = policyUpdate.OrganizationId;
organization.Id = policyUpdate.OrganizationId;
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
var orgUserDetailUserWithout2Fa = new OrganizationUserUserDetails
var nonCompliantUser = new OrganizationUserUserDetails
{
Id = Guid.NewGuid(),
Status = OrganizationUserStatusType.Confirmed,
@ -80,30 +83,57 @@ public class TwoFactorAuthenticationPolicyValidatorTests
HasMasterPassword = true
};
var compliantUser = new OrganizationUserUserDetails
{
Id = Guid.NewGuid(),
Status = OrganizationUserStatusType.Confirmed,
Type = OrganizationUserType.User,
Email = "user4@test.com",
Name = "TEST",
UserId = Guid.NewGuid(),
HasMasterPassword = true
};
sutProvider.GetDependency<IOrganizationUserRepository>()
.GetManyDetailsByOrganizationAsync(policyUpdate.OrganizationId)
.Returns([orgUserDetailUserWithout2Fa]);
.Returns([nonCompliantUser, compliantUser]);
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>()
.TwoFactorIsEnabledAsync(Arg.Any<IEnumerable<OrganizationUserUserDetails>>())
.Returns(new List<(OrganizationUserUserDetails user, bool hasTwoFactor)>()
{
(orgUserDetailUserWithout2Fa, false)
(nonCompliantUser, false),
(compliantUser, true)
});
sutProvider.GetDependency<IRevokeNonCompliantOrganizationUserCommand>()
.RevokeNonCompliantOrganizationUsersAsync(Arg.Any<RevokeOrganizationUsersRequest>())
.Returns(new CommandResult());
// Act
await sutProvider.Sut.OnSaveSideEffectsAsync(policyUpdate, policy);
// Assert
await sutProvider.GetDependency<IRevokeNonCompliantOrganizationUserCommand>()
.Received(1)
.RevokeNonCompliantOrganizationUsersAsync(Arg.Any<RevokeOrganizationUsersRequest>());
await sutProvider.GetDependency<IRevokeNonCompliantOrganizationUserCommand>()
.Received(1)
.RevokeNonCompliantOrganizationUsersAsync(Arg.Is<RevokeOrganizationUsersRequest>(req =>
req.OrganizationId == policyUpdate.OrganizationId &&
req.OrganizationUsers.SequenceEqual(new[] { nonCompliantUser })
));
await sutProvider.GetDependency<IMailService>()
.Received(1)
.SendOrganizationUserRevokedForTwoFactorPolicyEmailAsync(organization.DisplayName(),
"user3@test.com");
nonCompliantUser.Email);
// Did not send out an email for compliantUser
await sutProvider.GetDependency<IMailService>()
.Received(0)
.SendOrganizationUserRevokedForTwoFactorPolicyEmailAsync(organization.DisplayName(),
compliantUser.Email);
}
}