using Bit.Api.AdminConsole.Models.Request.Organizations; using Bit.Core.Entities; using Bit.Core.Exceptions; using Bit.Core.Repositories; namespace Bit.Api.KeyManagement.Validators; /// /// Organization user implementation for /// Currently responsible for validation of user reset password keys (used by admins to perform account recovery) during user key rotation /// public class OrganizationUserRotationValidator : IRotationValidator, IReadOnlyList> { private readonly IOrganizationUserRepository _organizationUserRepository; public OrganizationUserRotationValidator(IOrganizationUserRepository organizationUserRepository) => _organizationUserRepository = organizationUserRepository; public async Task> ValidateAsync(User user, IEnumerable resetPasswordKeys) { if (user == null) { throw new ArgumentNullException(nameof(user)); } var result = new List(); var existing = await _organizationUserRepository.GetManyByUserAsync(user.Id); if (existing == null || existing.Count == 0) { return result; } // Exclude any account recovery that do not have a key. existing = existing.Where(o => o.ResetPasswordKey != null).ToList(); foreach (var ou in existing) { var organizationUser = resetPasswordKeys.FirstOrDefault(a => a.OrganizationId == ou.OrganizationId); if (organizationUser == null) { throw new BadRequestException("All existing reset password keys must be included in the rotation."); } if (organizationUser.ResetPasswordKey == null) { throw new BadRequestException("Reset Password keys cannot be set to null during rotation."); } ou.ResetPasswordKey = organizationUser.ResetPasswordKey; result.Add(ou); } return result; } }