using Bit.Core.AdminConsole.Entities; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Repositories; using Xunit; namespace Bit.Infrastructure.IntegrationTest.Repositories; public class OrganizationUserRepositoryTests { [DatabaseTheory, DatabaseData] public async Task DeleteAsync_Works(IUserRepository userRepository, IOrganizationRepository organizationRepository, IOrganizationUserRepository organizationUserRepository) { var user = await userRepository.CreateAsync(new User { Name = "Test User", Email = $"test+{Guid.NewGuid()}@example.com", ApiKey = "TEST", SecurityStamp = "stamp", }); var organization = await organizationRepository.CreateAsync(new Organization { Name = "Test Org", BillingEmail = user.Email, // TODO: EF does not enfore this being NOT NULL Plan = "Test", // TODO: EF does not enforce this being NOT NULl }); var orgUser = await organizationUserRepository.CreateAsync(new OrganizationUser { OrganizationId = organization.Id, UserId = user.Id, Status = OrganizationUserStatusType.Confirmed, }); await organizationUserRepository.DeleteAsync(orgUser); var newUser = await userRepository.GetByIdAsync(user.Id); Assert.NotEqual(newUser.AccountRevisionDate, user.AccountRevisionDate); } [DatabaseTheory, DatabaseData] public async Task DeleteManyAsync_Works(IUserRepository userRepository, IOrganizationRepository organizationRepository, IOrganizationUserRepository organizationUserRepository) { var user1 = await userRepository.CreateAsync(new User { Name = "Test User 1", Email = $"test+{Guid.NewGuid()}@email.com", ApiKey = "TEST", SecurityStamp = "stamp", }); var user2 = await userRepository.CreateAsync(new User { Name = "Test User 2", Email = $"test+{Guid.NewGuid()}@email.com", ApiKey = "TEST", SecurityStamp = "stamp", }); var organization = await organizationRepository.CreateAsync(new Organization { Name = "Test Org", BillingEmail = user1.Email, // TODO: EF does not enforce this being NOT NULl Plan = "Test", // TODO: EF does not enforce this being NOT NULl }); var orgUser1 = await organizationUserRepository.CreateAsync(new OrganizationUser { OrganizationId = organization.Id, UserId = user1.Id, Status = OrganizationUserStatusType.Confirmed, }); var orgUser2 = await organizationUserRepository.CreateAsync(new OrganizationUser { OrganizationId = organization.Id, UserId = user2.Id, Status = OrganizationUserStatusType.Confirmed, }); await organizationUserRepository.DeleteManyAsync(new List { orgUser1.Id, orgUser2.Id, }); var updatedUser1 = await userRepository.GetByIdAsync(user1.Id); var updatedUser2 = await userRepository.GetByIdAsync(user2.Id); Assert.NotEqual(updatedUser1.AccountRevisionDate, user1.AccountRevisionDate); Assert.NotEqual(updatedUser2.AccountRevisionDate, user2.AccountRevisionDate); } [DatabaseTheory, DatabaseData] public async Task GetManyAccountRecoveryDetailsByOrganizationUserAsync_Works(IUserRepository userRepository, IOrganizationRepository organizationRepository, IOrganizationUserRepository organizationUserRepository) { var user1 = await userRepository.CreateAsync(new User { Name = "Test User 1", Email = $"test+{Guid.NewGuid()}@example.com", ApiKey = "TEST", SecurityStamp = "stamp", Kdf = KdfType.PBKDF2_SHA256, KdfIterations = 1, KdfMemory = 2, KdfParallelism = 3 }); var user2 = await userRepository.CreateAsync(new User { Name = "Test User 2", Email = $"test+{Guid.NewGuid()}@example.com", ApiKey = "TEST", SecurityStamp = "stamp", Kdf = KdfType.Argon2id, KdfIterations = 4, KdfMemory = 5, KdfParallelism = 6 }); var organization = await organizationRepository.CreateAsync(new Organization { Name = "Test Org", BillingEmail = user1.Email, // TODO: EF does not enforce this being NOT NULl Plan = "Test", // TODO: EF does not enforce this being NOT NULl PrivateKey = "privatekey", }); var orgUser1 = await organizationUserRepository.CreateAsync(new OrganizationUser { OrganizationId = organization.Id, UserId = user1.Id, Status = OrganizationUserStatusType.Confirmed, ResetPasswordKey = "resetpasswordkey1", }); var orgUser2 = await organizationUserRepository.CreateAsync(new OrganizationUser { OrganizationId = organization.Id, UserId = user2.Id, Status = OrganizationUserStatusType.Confirmed, ResetPasswordKey = "resetpasswordkey2", }); var recoveryDetails = await organizationUserRepository.GetManyAccountRecoveryDetailsByOrganizationUserAsync( organization.Id, new[] { orgUser1.Id, orgUser2.Id, }); Assert.NotNull(recoveryDetails); Assert.Equal(2, recoveryDetails.Count()); Assert.Contains(recoveryDetails, r => r.OrganizationUserId == orgUser1.Id && r.Kdf == KdfType.PBKDF2_SHA256 && r.KdfIterations == 1 && r.KdfMemory == 2 && r.KdfParallelism == 3 && r.ResetPasswordKey == "resetpasswordkey1" && r.EncryptedPrivateKey == "privatekey"); Assert.Contains(recoveryDetails, r => r.OrganizationUserId == orgUser2.Id && r.Kdf == KdfType.Argon2id && r.KdfIterations == 4 && r.KdfMemory == 5 && r.KdfParallelism == 6 && r.ResetPasswordKey == "resetpasswordkey2" && r.EncryptedPrivateKey == "privatekey"); } }