1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 15:42:48 -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

@ -2,6 +2,7 @@
using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Identity.TokenProviders;
using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Models.Data.Organizations;
@ -27,11 +28,11 @@ public class TwoFactorAuthenticationValidatorTests
private readonly IUserService _userService;
private readonly UserManagerTestWrapper<User> _userManager;
private readonly IOrganizationDuoUniversalTokenProvider _organizationDuoUniversalTokenProvider;
private readonly IFeatureService _featureService;
private readonly IApplicationCacheService _applicationCacheService;
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IOrganizationRepository _organizationRepository;
private readonly IDataProtectorTokenFactory<SsoEmail2faSessionTokenable> _ssoEmail2faSessionTokenable;
private readonly ITwoFactorIsEnabledQuery _twoFactorenabledQuery;
private readonly ICurrentContext _currentContext;
private readonly TwoFactorAuthenticationValidator _sut;
@ -40,22 +41,22 @@ public class TwoFactorAuthenticationValidatorTests
_userService = Substitute.For<IUserService>();
_userManager = SubstituteUserManager();
_organizationDuoUniversalTokenProvider = Substitute.For<IOrganizationDuoUniversalTokenProvider>();
_featureService = Substitute.For<IFeatureService>();
_applicationCacheService = Substitute.For<IApplicationCacheService>();
_organizationUserRepository = Substitute.For<IOrganizationUserRepository>();
_organizationRepository = Substitute.For<IOrganizationRepository>();
_ssoEmail2faSessionTokenable = Substitute.For<IDataProtectorTokenFactory<SsoEmail2faSessionTokenable>>();
_twoFactorenabledQuery = Substitute.For<ITwoFactorIsEnabledQuery>();
_currentContext = Substitute.For<ICurrentContext>();
_sut = new TwoFactorAuthenticationValidator(
_userService,
_userManager,
_organizationDuoUniversalTokenProvider,
_featureService,
_applicationCacheService,
_organizationUserRepository,
_organizationRepository,
_ssoEmail2faSessionTokenable,
_twoFactorenabledQuery,
_currentContext);
}
@ -263,9 +264,6 @@ public class TwoFactorAuthenticationValidatorTests
_userManager.SUPPORTS_TWO_FACTOR = true;
_userManager.TWO_FACTOR_PROVIDERS = [providerType.ToString()];
_userService.TwoFactorProviderIsEnabledAsync(Arg.Any<TwoFactorProviderType>(), user)
.Returns(true);
// Act
var result = await _sut.BuildTwoFactorResultAsync(user, null);
@ -322,9 +320,6 @@ public class TwoFactorAuthenticationValidatorTests
string token)
{
// Arrange
_userService.TwoFactorProviderIsEnabledAsync(
TwoFactorProviderType.Email, user).Returns(true);
_userManager.TWO_FACTOR_PROVIDERS = ["email"];
// Act
@ -342,10 +337,8 @@ public class TwoFactorAuthenticationValidatorTests
string token)
{
// Arrange
_userService.TwoFactorProviderIsEnabledAsync(
TwoFactorProviderType.Email, user).Returns(false);
_userManager.TWO_FACTOR_PROVIDERS = ["email"];
user.TwoFactorProviders = "";
// Act
var result = await _sut.VerifyTwoFactorAsync(
@ -362,9 +355,6 @@ public class TwoFactorAuthenticationValidatorTests
string token)
{
// Arrange
_userService.TwoFactorProviderIsEnabledAsync(
TwoFactorProviderType.OrganizationDuo, user).Returns(false);
_userManager.TWO_FACTOR_PROVIDERS = ["OrganizationDuo"];
// Act
@ -387,11 +377,9 @@ public class TwoFactorAuthenticationValidatorTests
string token)
{
// Arrange
_userService.TwoFactorProviderIsEnabledAsync(
providerType, user).Returns(true);
_userManager.TWO_FACTOR_ENABLED = true;
_userManager.TWO_FACTOR_TOKEN_VERIFIED = true;
user.TwoFactorProviders = GetTwoFactorIndividualProviderJson(providerType);
// Act
var result = await _sut.VerifyTwoFactorAsync(user, null, providerType, token);
@ -412,11 +400,9 @@ public class TwoFactorAuthenticationValidatorTests
string token)
{
// Arrange
_userService.TwoFactorProviderIsEnabledAsync(
providerType, user).Returns(true);
_userManager.TWO_FACTOR_ENABLED = true;
_userManager.TWO_FACTOR_TOKEN_VERIFIED = false;
user.TwoFactorProviders = GetTwoFactorIndividualProviderJson(providerType);
// Act
var result = await _sut.VerifyTwoFactorAsync(user, null, providerType, token);