1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-24 12:35:25 +01:00

Add a master password hash check to account recovery enrollment (#4154)

This commit is contained in:
Addison Beck 2024-07-01 11:52:58 -04:00 committed by GitHub
parent 5fcd281d96
commit e2d2a2ba90
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 36 additions and 1 deletions

View File

@ -456,6 +456,11 @@ public class OrganizationUsersController : Controller
throw new UnauthorizedAccessException();
}
if (!string.IsNullOrWhiteSpace(model.ResetPasswordKey) && !await _userService.VerifySecretAsync(user, model.Secret))
{
throw new BadRequestException("Incorrect password");
}
var callingUserId = user.Id;
await _organizationService.UpdateUserResetPasswordEnrollmentAsync(
orgId, userId, model.ResetPasswordKey, callingUserId);

View File

@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using Bit.Api.Auth.Models.Request.Accounts;
using Bit.Api.Models.Request;
using Bit.Core.Entities;
using Bit.Core.Enums;
@ -98,7 +99,7 @@ public class OrganizationUserUpdateRequestModel
}
}
public class OrganizationUserResetPasswordEnrollmentRequestModel
public class OrganizationUserResetPasswordEnrollmentRequestModel : SecretVerificationRequestModel
{
public string ResetPasswordKey { get; set; }
}

View File

@ -40,6 +40,7 @@ public class OrganizationUsersControllerTests
{
orgUser.Status = Core.Enums.OrganizationUserStatusType.Invited;
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(user);
sutProvider.GetDependency<IUserService>().VerifySecretAsync(default, default).ReturnsForAnyArgs(true);
sutProvider.GetDependency<IOrganizationUserRepository>().GetByOrganizationAsync(default, default).ReturnsForAnyArgs(orgUser);
await sutProvider.Sut.PutResetPasswordEnrollment(orgId, userId, model);
@ -54,6 +55,7 @@ public class OrganizationUsersControllerTests
{
orgUser.Status = Core.Enums.OrganizationUserStatusType.Confirmed;
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(user);
sutProvider.GetDependency<IUserService>().VerifySecretAsync(default, default).ReturnsForAnyArgs(true);
sutProvider.GetDependency<IOrganizationUserRepository>().GetByOrganizationAsync(default, default).ReturnsForAnyArgs(orgUser);
await sutProvider.Sut.PutResetPasswordEnrollment(orgId, userId, model);
@ -61,6 +63,33 @@ public class OrganizationUsersControllerTests
await sutProvider.GetDependency<IAcceptOrgUserCommand>().Received(0).AcceptOrgUserByOrgIdAsync(orgId, user, sutProvider.GetDependency<IUserService>());
}
[Theory]
[BitAutoData]
public async Task PutResetPasswordEnrollment_PasswordValidationFails_Throws(Guid orgId, Guid userId, OrganizationUserResetPasswordEnrollmentRequestModel model,
User user, SutProvider<OrganizationUsersController> sutProvider)
{
model.MasterPasswordHash = "NotThePassword";
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(user);
await Assert.ThrowsAsync<BadRequestException>(async () => await sutProvider.Sut.PutResetPasswordEnrollment(orgId, userId, model));
}
[Theory]
[BitAutoData]
public async Task PutResetPasswordEnrollment_PasswordValidationPasses_Continues(Guid orgId, Guid userId, OrganizationUserResetPasswordEnrollmentRequestModel model,
User user, OrganizationUser orgUser, SutProvider<OrganizationUsersController> sutProvider)
{
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(user);
sutProvider.GetDependency<IUserService>().VerifySecretAsync(user, model.Secret).Returns(true);
sutProvider.GetDependency<IOrganizationUserRepository>().GetByOrganizationAsync(default, default).ReturnsForAnyArgs(orgUser);
await sutProvider.Sut.PutResetPasswordEnrollment(orgId, userId, model);
await sutProvider.GetDependency<IOrganizationService>().Received(1).UpdateUserResetPasswordEnrollmentAsync(
orgId,
userId,
model.ResetPasswordKey,
user.Id
);
}
[Theory]
[BitAutoData]
public async Task Accept_RequiresKnownUser(Guid orgId, Guid orgUserId, OrganizationUserAcceptRequestModel model,