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:
@ -5,6 +5,7 @@ using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using NSubstitute;
|
||||
@ -53,6 +54,39 @@ public class TwoFactorIsEnabledQueryTests
|
||||
}
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task TwoFactorIsEnabledQuery_DatabaseReturnsEmpty_ResultEmpty(
|
||||
SutProvider<TwoFactorIsEnabledQuery> sutProvider,
|
||||
List<UserWithCalculatedPremium> usersWithCalculatedPremium)
|
||||
{
|
||||
// Arrange
|
||||
var userIds = usersWithCalculatedPremium.Select(u => u.Id).ToList();
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetManyWithCalculatedPremiumAsync(Arg.Any<IEnumerable<Guid>>())
|
||||
.Returns([]);
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(userIds);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData((IEnumerable<Guid>)null)]
|
||||
[BitAutoData([])]
|
||||
public async Task TwoFactorIsEnabledQuery_UserIdsNullorEmpty_ResultEmpty(
|
||||
IEnumerable<Guid> userIds,
|
||||
SutProvider<TwoFactorIsEnabledQuery> sutProvider)
|
||||
{
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(userIds);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task TwoFactorIsEnabledQuery_WithNoTwoFactorEnabled_ReturnsAllTwoFactorDisabled(
|
||||
@ -122,8 +156,11 @@ public class TwoFactorIsEnabledQueryTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task TwoFactorIsEnabledQuery_WithNullTwoFactorProviders_ReturnsAllTwoFactorDisabled(
|
||||
[BitAutoData("")]
|
||||
[BitAutoData("{}")]
|
||||
[BitAutoData((string)null)]
|
||||
public async Task TwoFactorIsEnabledQuery_WithNullOrEmptyTwoFactorProviders_ReturnsAllTwoFactorDisabled(
|
||||
string twoFactorProviders,
|
||||
SutProvider<TwoFactorIsEnabledQuery> sutProvider,
|
||||
List<UserWithCalculatedPremium> usersWithCalculatedPremium)
|
||||
{
|
||||
@ -132,7 +169,7 @@ public class TwoFactorIsEnabledQueryTests
|
||||
|
||||
foreach (var user in usersWithCalculatedPremium)
|
||||
{
|
||||
user.TwoFactorProviders = null; // No two-factor providers configured
|
||||
user.TwoFactorProviders = twoFactorProviders; // No two-factor providers configured
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
@ -176,6 +213,24 @@ public class TwoFactorIsEnabledQueryTests
|
||||
.GetManyWithCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task TwoFactorIsEnabledQuery_UserIdNull_ReturnsFalse(
|
||||
SutProvider<TwoFactorIsEnabledQuery> sutProvider)
|
||||
{
|
||||
// Arrange
|
||||
var user = new TestTwoFactorProviderUser
|
||||
{
|
||||
Id = null
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(user);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(TwoFactorProviderType.Authenticator)]
|
||||
[BitAutoData(TwoFactorProviderType.Email)]
|
||||
@ -193,10 +248,8 @@ public class TwoFactorIsEnabledQueryTests
|
||||
{ freeProviderType, new TwoFactorProvider { Enabled = true } }
|
||||
};
|
||||
|
||||
user.Premium = false;
|
||||
user.SetTwoFactorProviders(twoFactorProviders);
|
||||
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(user);
|
||||
|
||||
@ -205,7 +258,7 @@ public class TwoFactorIsEnabledQueryTests
|
||||
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.GetManyWithCalculatedPremiumAsync(default);
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -230,7 +283,7 @@ public class TwoFactorIsEnabledQueryTests
|
||||
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.GetManyWithCalculatedPremiumAsync(default);
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -252,14 +305,18 @@ public class TwoFactorIsEnabledQueryTests
|
||||
user.SetTwoFactorProviders(twoFactorProviders);
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetManyWithCalculatedPremiumAsync(Arg.Is<IEnumerable<Guid>>(i => i.Contains(user.Id)))
|
||||
.Returns(new List<UserWithCalculatedPremium> { user });
|
||||
.GetCalculatedPremiumAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(user);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.ReceivedWithAnyArgs(1)
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -268,7 +325,7 @@ public class TwoFactorIsEnabledQueryTests
|
||||
public async Task TwoFactorIsEnabledQuery_WithProviderTypeRequiringPremium_WithUserPremium_ReturnsTrue(
|
||||
TwoFactorProviderType premiumProviderType,
|
||||
SutProvider<TwoFactorIsEnabledQuery> sutProvider,
|
||||
User user)
|
||||
UserWithCalculatedPremium user)
|
||||
{
|
||||
// Arrange
|
||||
var twoFactorProviders = new Dictionary<TwoFactorProviderType, TwoFactorProvider>
|
||||
@ -276,9 +333,14 @@ public class TwoFactorIsEnabledQueryTests
|
||||
{ premiumProviderType, new TwoFactorProvider { Enabled = true } }
|
||||
};
|
||||
|
||||
user.Premium = true;
|
||||
user.Premium = false;
|
||||
user.HasPremiumAccess = true;
|
||||
user.SetTwoFactorProviders(twoFactorProviders);
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetCalculatedPremiumAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(user);
|
||||
|
||||
@ -286,8 +348,8 @@ public class TwoFactorIsEnabledQueryTests
|
||||
Assert.True(result);
|
||||
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.GetManyWithCalculatedPremiumAsync(default);
|
||||
.ReceivedWithAnyArgs(1)
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -309,14 +371,18 @@ public class TwoFactorIsEnabledQueryTests
|
||||
user.SetTwoFactorProviders(twoFactorProviders);
|
||||
|
||||
sutProvider.GetDependency<IUserRepository>()
|
||||
.GetManyWithCalculatedPremiumAsync(Arg.Is<IEnumerable<Guid>>(i => i.Contains(user.Id)))
|
||||
.Returns(new List<UserWithCalculatedPremium> { user });
|
||||
.GetCalculatedPremiumAsync(user.Id)
|
||||
.Returns(user);
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.TwoFactorIsEnabledAsync(user);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.ReceivedWithAnyArgs(1)
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -333,5 +399,29 @@ public class TwoFactorIsEnabledQueryTests
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
await sutProvider.GetDependency<IUserRepository>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.GetCalculatedPremiumAsync(default);
|
||||
}
|
||||
|
||||
private class TestTwoFactorProviderUser : ITwoFactorProvidersUser
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string TwoFactorProviders { get; set; }
|
||||
public bool Premium { get; set; }
|
||||
public Dictionary<TwoFactorProviderType, TwoFactorProvider> GetTwoFactorProviders()
|
||||
{
|
||||
return JsonHelpers.LegacyDeserialize<Dictionary<TwoFactorProviderType, TwoFactorProvider>>(TwoFactorProviders);
|
||||
}
|
||||
|
||||
public Guid? GetUserId()
|
||||
{
|
||||
return Id;
|
||||
}
|
||||
|
||||
public bool GetPremium()
|
||||
{
|
||||
return Premium;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user