1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-17 00:03:17 -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)); throw new BadRequestException(string.Join(", ", commandResult.ErrorMessages));
} }
await Task.WhenAll(currentActiveRevocableOrganizationUsers.Select(x => await Task.WhenAll(nonCompliantUsers.Select(nonCompliantUser =>
_mailService.SendOrganizationUserRevokedForTwoFactorPolicyEmailAsync(organization.DisplayName(), x.Email))); _mailService.SendOrganizationUserRevokedForTwoFactorPolicyEmailAsync(organization.DisplayName(), nonCompliantUser.user.Email)));
} }
private static bool MembersWithNoMasterPasswordWillLoseAccess( private static bool MembersWithNoMasterPasswordWillLoseAccess(

View File

@ -60,16 +60,19 @@ public class TwoFactorAuthenticationPolicyValidatorTests
} }
[Theory, BitAutoData] [Theory, BitAutoData]
public async Task OnSaveSideEffectsAsync_RevokesNonCompliantUsers( public async Task OnSaveSideEffectsAsync_RevokesOnlyNonCompliantUsers(
Organization organization, Organization organization,
[PolicyUpdate(PolicyType.TwoFactorAuthentication)] PolicyUpdate policyUpdate, [PolicyUpdate(PolicyType.TwoFactorAuthentication)] PolicyUpdate policyUpdate,
[Policy(PolicyType.TwoFactorAuthentication, false)] Policy policy, [Policy(PolicyType.TwoFactorAuthentication, false)] Policy policy,
SutProvider<TwoFactorAuthenticationPolicyValidator> sutProvider) 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); sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
var orgUserDetailUserWithout2Fa = new OrganizationUserUserDetails var nonCompliantUser = new OrganizationUserUserDetails
{ {
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
Status = OrganizationUserStatusType.Confirmed, Status = OrganizationUserStatusType.Confirmed,
@ -80,30 +83,57 @@ public class TwoFactorAuthenticationPolicyValidatorTests
HasMasterPassword = true 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>() sutProvider.GetDependency<IOrganizationUserRepository>()
.GetManyDetailsByOrganizationAsync(policyUpdate.OrganizationId) .GetManyDetailsByOrganizationAsync(policyUpdate.OrganizationId)
.Returns([orgUserDetailUserWithout2Fa]); .Returns([nonCompliantUser, compliantUser]);
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>() sutProvider.GetDependency<ITwoFactorIsEnabledQuery>()
.TwoFactorIsEnabledAsync(Arg.Any<IEnumerable<OrganizationUserUserDetails>>()) .TwoFactorIsEnabledAsync(Arg.Any<IEnumerable<OrganizationUserUserDetails>>())
.Returns(new List<(OrganizationUserUserDetails user, bool hasTwoFactor)>() .Returns(new List<(OrganizationUserUserDetails user, bool hasTwoFactor)>()
{ {
(orgUserDetailUserWithout2Fa, false) (nonCompliantUser, false),
(compliantUser, true)
}); });
sutProvider.GetDependency<IRevokeNonCompliantOrganizationUserCommand>() sutProvider.GetDependency<IRevokeNonCompliantOrganizationUserCommand>()
.RevokeNonCompliantOrganizationUsersAsync(Arg.Any<RevokeOrganizationUsersRequest>()) .RevokeNonCompliantOrganizationUsersAsync(Arg.Any<RevokeOrganizationUsersRequest>())
.Returns(new CommandResult()); .Returns(new CommandResult());
// Act
await sutProvider.Sut.OnSaveSideEffectsAsync(policyUpdate, policy); await sutProvider.Sut.OnSaveSideEffectsAsync(policyUpdate, policy);
// Assert
await sutProvider.GetDependency<IRevokeNonCompliantOrganizationUserCommand>() await sutProvider.GetDependency<IRevokeNonCompliantOrganizationUserCommand>()
.Received(1) .Received(1)
.RevokeNonCompliantOrganizationUsersAsync(Arg.Any<RevokeOrganizationUsersRequest>()); .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>() await sutProvider.GetDependency<IMailService>()
.Received(1) .Received(1)
.SendOrganizationUserRevokedForTwoFactorPolicyEmailAsync(organization.DisplayName(), .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);
} }
} }