mirror of
https://github.com/bitwarden/server
synced 2026-02-25 08:53:21 +00:00
[PM-21179] Add interface to check if user is enrolled in account recovery (#6993)
* Add validation for reset password key and account recovery enrollment in OrganizationUser * Update admin approval logic to check account recovery enrollment and add tests for reset password key validation * Enhance UserService validation to include account recovery enrollment and add unit test for empty or whitespace reset password key handling * Refactor OrganizationUserUserDetailsQuery to validate reset password keys and add unit tests for filtering out invalid keys * Update AdminRecoverAccountCommand to validate account recovery enrollment and adjust tests for whitespace reset password keys * Enhance OrganizationUserRotationValidator to validate reset password keys, including filtering out whitespace-only keys, and add corresponding unit tests for validation logic. * Refactor OrganizationUserUserDetailsQueryTests to remove unnecessary whitespace-only test cases for account recovery key validation. * Refactor MemberResponseModel to use OrganizationUser's validation method for ResetPasswordEnrolled status and update corresponding unit test for clarity. * Refactor OrganizationUsersController and response models to utilize OrganizationUser's validation method for ResetPasswordKey, ensuring consistent validation across the application. Add unit tests for OrganizationUser to verify key validation logic. * Update OrganizationUserRotationValidator to handle null reset password keys and adjust tests for client-side bug. Add comments for future migration after resolving PM-31001. * Fix whitespace issue in UserServiceTests.cs by removing BOM character from the file header.
This commit is contained in:
@@ -199,4 +199,77 @@ public class OrganizationUserRotationValidatorTests
|
||||
await Assert.ThrowsAsync<BadRequestException>(async () =>
|
||||
await sutProvider.Sut.ValidateAsync(user, Enumerable.Empty<ResetPasswordWithOrgIdRequestModel>()));
|
||||
}
|
||||
|
||||
// TODO: Remove this test after https://bitwarden.atlassian.net/browse/PM-31001 is resolved.
|
||||
// Clients currently send "" as a reset password key value during rotation due to a client-side bug.
|
||||
// The server must accept "" to avoid blocking key rotation for affected users.
|
||||
// After PM-31001 is fixed, this should be replaced with a test asserting that "" throws BadRequestException.
|
||||
[Theory]
|
||||
[BitAutoData("")]
|
||||
[BitAutoData(" ")]
|
||||
public async Task ValidateAsync_EmptyOrWhitespaceKey_AcceptedDueToClientBug(
|
||||
string emptyKey,
|
||||
SutProvider<OrganizationUserRotationValidator> sutProvider, User user,
|
||||
ResetPasswordWithOrgIdRequestModel validResetPasswordKey)
|
||||
{
|
||||
// Arrange
|
||||
var existingUserResetPassword = new List<OrganizationUser>
|
||||
{
|
||||
new OrganizationUser
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
OrganizationId = validResetPasswordKey.OrganizationId,
|
||||
ResetPasswordKey = "existing-valid-key"
|
||||
}
|
||||
};
|
||||
sutProvider.GetDependency<IOrganizationUserRepository>().GetManyByUserAsync(user.Id)
|
||||
.Returns(existingUserResetPassword);
|
||||
|
||||
// Set the incoming key to empty/whitespace (simulating client bug)
|
||||
validResetPasswordKey.ResetPasswordKey = emptyKey;
|
||||
|
||||
// Act — rotation should succeed (not throw) to preserve backward compatibility
|
||||
var result = await sutProvider.Sut.ValidateAsync(user, new[] { validResetPasswordKey });
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(result);
|
||||
Assert.Single(result);
|
||||
Assert.Equal(emptyKey, result[0].ResetPasswordKey);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(" ")]
|
||||
public async Task ValidateAsync_WhitespaceOnlyExistingKey_FiltersOut(
|
||||
string whitespaceKey,
|
||||
SutProvider<OrganizationUserRotationValidator> sutProvider, User user,
|
||||
ResetPasswordWithOrgIdRequestModel validResetPasswordKey)
|
||||
{
|
||||
// Arrange
|
||||
var existingUserResetPassword = new List<OrganizationUser>
|
||||
{
|
||||
new OrganizationUser
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
OrganizationId = validResetPasswordKey.OrganizationId,
|
||||
ResetPasswordKey = validResetPasswordKey.ResetPasswordKey
|
||||
},
|
||||
// Whitespace-only key should be filtered out
|
||||
new OrganizationUser
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
OrganizationId = Guid.NewGuid(),
|
||||
ResetPasswordKey = whitespaceKey
|
||||
}
|
||||
};
|
||||
sutProvider.GetDependency<IOrganizationUserRepository>().GetManyByUserAsync(user.Id)
|
||||
.Returns(existingUserResetPassword);
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.ValidateAsync(user, new[] { validResetPasswordKey });
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(result);
|
||||
Assert.Single(result);
|
||||
Assert.Equal(validResetPasswordKey.OrganizationId, result[0].OrganizationId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user