1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 07:36:14 -05:00

[PM-19029][PM-19203] Addressing UserService tech debt around ITwoFactorIsEnabledQuery (#5754)

* fix : split out the interface from the TwoFactorAuthenticationValidator into separate file.
* fix: replacing IUserService.TwoFactorEnabled with ITwoFactorEnabledQuery
* fix: combined logic for both bulk and single user look ups for TwoFactorIsEnabledQuery.
* fix: return two factor provider enabled on CanGenerate() method.

* tech debt: modfifying MFA providers to call the database less to validate if two factor is enabled. 
* tech debt: removed unused service from AuthenticatorTokenProvider

* doc: added documentation to ITwoFactorProviderUsers
* doc: updated comments for TwoFactorIsEnabled impl

* test: fixing tests for ITwoFactorIsEnabledQuery
* test: updating tests to have correct DI and removing test for automatic email of TOTP.
* test: adding better test coverage
This commit is contained in:
Ike
2025-05-09 11:39:57 -04:00
committed by GitHub
parent 80e7a0afd6
commit 3f95513d11
31 changed files with 372 additions and 259 deletions

View File

@ -8,6 +8,7 @@ using Bit.Core.AdminConsole.Enums.Provider;
using Bit.Core.AdminConsole.Models.Data.Provider;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Auth.Models;
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
@ -64,6 +65,7 @@ public class SyncControllerTests
{
// Get dependencies
var userService = sutProvider.GetDependency<IUserService>();
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
var providerUserRepository = sutProvider.GetDependency<IProviderUserRepository>();
var folderRepository = sutProvider.GetDependency<IFolderRepository>();
@ -119,7 +121,7 @@ public class SyncControllerTests
collectionRepository.GetManyByUserIdAsync(user.Id).Returns(collections);
collectionCipherRepository.GetManyByUserIdAsync(user.Id).Returns(new List<CollectionCipher>());
// Back to standard test setup
userService.TwoFactorIsEnabledAsync(user).Returns(false);
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(user).Returns(false);
userService.HasPremiumFromOrganization(user).Returns(false);
// Execute GET
@ -129,7 +131,7 @@ public class SyncControllerTests
// Asserts
// Assert that methods are called
var hasEnabledOrgs = organizationUserDetails.Any(o => o.Enabled);
await this.AssertMethodsCalledAsync(userService, organizationUserRepository, providerUserRepository, folderRepository,
await this.AssertMethodsCalledAsync(userService, twoFactorIsEnabledQuery, organizationUserRepository, providerUserRepository, folderRepository,
cipherRepository, sendRepository, collectionRepository, collectionCipherRepository, hasEnabledOrgs);
Assert.IsType<SyncResponseModel>(result);
@ -155,6 +157,7 @@ public class SyncControllerTests
{
// Get dependencies
var userService = sutProvider.GetDependency<IUserService>();
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
var providerUserRepository = sutProvider.GetDependency<IProviderUserRepository>();
var folderRepository = sutProvider.GetDependency<IFolderRepository>();
@ -205,7 +208,7 @@ public class SyncControllerTests
policyRepository.GetManyByUserIdAsync(user.Id).Returns(policies);
userService.TwoFactorIsEnabledAsync(user).Returns(false);
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(user).Returns(false);
userService.HasPremiumFromOrganization(user).Returns(false);
// Execute GET
@ -216,7 +219,7 @@ public class SyncControllerTests
// Assert that methods are called
var hasEnabledOrgs = organizationUserDetails.Any(o => o.Enabled);
await this.AssertMethodsCalledAsync(userService, organizationUserRepository, providerUserRepository, folderRepository,
await this.AssertMethodsCalledAsync(userService, twoFactorIsEnabledQuery, organizationUserRepository, providerUserRepository, folderRepository,
cipherRepository, sendRepository, collectionRepository, collectionCipherRepository, hasEnabledOrgs);
Assert.IsType<SyncResponseModel>(result);
@ -244,6 +247,7 @@ public class SyncControllerTests
{
// Get dependencies
var userService = sutProvider.GetDependency<IUserService>();
var twoFactorIsEnabledQuery = sutProvider.GetDependency<ITwoFactorIsEnabledQuery>();
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
var providerUserRepository = sutProvider.GetDependency<IProviderUserRepository>();
var folderRepository = sutProvider.GetDependency<IFolderRepository>();
@ -283,7 +287,7 @@ public class SyncControllerTests
collectionRepository.GetManyByUserIdAsync(user.Id).Returns(collections);
collectionCipherRepository.GetManyByUserIdAsync(user.Id).Returns(new List<CollectionCipher>());
// Back to standard test setup
userService.TwoFactorIsEnabledAsync(user).Returns(false);
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(user).Returns(false);
userService.HasPremiumFromOrganization(user).Returns(false);
// Execute GET
@ -293,7 +297,7 @@ public class SyncControllerTests
// Assert that methods are called
var hasEnabledOrgs = organizationUserDetails.Any(o => o.Enabled);
await this.AssertMethodsCalledAsync(userService, organizationUserRepository, providerUserRepository, folderRepository,
await this.AssertMethodsCalledAsync(userService, twoFactorIsEnabledQuery, organizationUserRepository, providerUserRepository, folderRepository,
cipherRepository, sendRepository, collectionRepository, collectionCipherRepository, hasEnabledOrgs);
Assert.IsType<SyncResponseModel>(result);
@ -315,6 +319,7 @@ public class SyncControllerTests
private async Task AssertMethodsCalledAsync(IUserService userService,
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
IOrganizationUserRepository organizationUserRepository,
IProviderUserRepository providerUserRepository, IFolderRepository folderRepository,
ICipherRepository cipherRepository, ISendRepository sendRepository,
@ -356,7 +361,7 @@ public class SyncControllerTests
.GetManyByUserIdAsync(default);
}
await userService.ReceivedWithAnyArgs(1)
await twoFactorIsEnabledQuery.ReceivedWithAnyArgs(1)
.TwoFactorIsEnabledAsync(default(ITwoFactorProvidersUser));
await userService.ReceivedWithAnyArgs(1)
.HasPremiumFromOrganization(default);