mirror of
https://github.com/bitwarden/server
synced 2025-12-10 13:23:27 +00:00
* feat: - Add SendPasswordHasher class and interface - DI for SendPasswordHasher to use Marker class allowing us to use custom options for the SendPasswordHasher without impacting other PasswordHashers. * test: Unit tests for SendPasswordHasher implementation * doc: docs for interface and comments Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com>
104 lines
3.8 KiB
C#
104 lines
3.8 KiB
C#
using Bit.Core.KeyManagement.Sends;
|
|
using Bit.Test.Common.AutoFixture;
|
|
using Bit.Test.Common.AutoFixture.Attributes;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using NSubstitute;
|
|
using Xunit;
|
|
|
|
namespace Bit.Core.Test.KeyManagement.Sends;
|
|
|
|
[SutProviderCustomize]
|
|
public class SendPasswordHasherTests
|
|
{
|
|
[Theory]
|
|
[BitAutoData(PasswordVerificationResult.Success)]
|
|
[BitAutoData(PasswordVerificationResult.SuccessRehashNeeded)]
|
|
void VerifyPasswordHash_WithValidMatching_ReturnsTrue(
|
|
PasswordVerificationResult passwordVerificationResult,
|
|
SutProvider<SendPasswordHasher> sutProvider,
|
|
string sendPasswordHash,
|
|
string inputPasswordHash)
|
|
{
|
|
// Arrange
|
|
sutProvider.GetDependency<IPasswordHasher<SendPasswordHasherMarker>>()
|
|
.VerifyHashedPassword(Arg.Any<SendPasswordHasherMarker>(), sendPasswordHash, inputPasswordHash)
|
|
.Returns(passwordVerificationResult);
|
|
|
|
// Act
|
|
var result = sutProvider.Sut.PasswordHashMatches(sendPasswordHash, inputPasswordHash);
|
|
|
|
// Assert
|
|
Assert.True(result);
|
|
sutProvider.GetDependency<IPasswordHasher<SendPasswordHasherMarker>>()
|
|
.Received(1)
|
|
.VerifyHashedPassword(Arg.Any<SendPasswordHasherMarker>(), sendPasswordHash, inputPasswordHash);
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
void VerifyPasswordHash_WithNonMatchingPasswords_ReturnsFalse(
|
|
SutProvider<SendPasswordHasher> sutProvider,
|
|
string sendPasswordHash,
|
|
string inputPasswordHash)
|
|
{
|
|
// Arrange
|
|
sutProvider.GetDependency<IPasswordHasher<SendPasswordHasherMarker>>()
|
|
.VerifyHashedPassword(Arg.Any<SendPasswordHasherMarker>(), sendPasswordHash, inputPasswordHash)
|
|
.Returns(PasswordVerificationResult.Failed);
|
|
|
|
// Act
|
|
var result = sutProvider.Sut.PasswordHashMatches(sendPasswordHash, inputPasswordHash);
|
|
|
|
// Assert
|
|
Assert.False(result);
|
|
sutProvider.GetDependency<IPasswordHasher<SendPasswordHasherMarker>>()
|
|
.Received(1)
|
|
.VerifyHashedPassword(Arg.Any<SendPasswordHasherMarker>(), sendPasswordHash, inputPasswordHash);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(null, "inputPassword")]
|
|
[InlineData("", "inputPassword")]
|
|
[InlineData(" ", "inputPassword")]
|
|
[InlineData("sendPassword", null)]
|
|
[InlineData("sendPassword", "")]
|
|
[InlineData("sendPassword", " ")]
|
|
[InlineData(null, null)]
|
|
[InlineData("", "")]
|
|
public void VerifyPasswordHash_WithNullOrEmptyParameters_ReturnsFalse(
|
|
string? sendPasswordHash,
|
|
string? inputPasswordHash)
|
|
{
|
|
// Arrange
|
|
var passwordHasher = Substitute.For<IPasswordHasher<SendPasswordHasherMarker>>();
|
|
var sut = new SendPasswordHasher(passwordHasher);
|
|
|
|
// Act
|
|
var result = sut.PasswordHashMatches(sendPasswordHash, inputPasswordHash);
|
|
|
|
// Assert
|
|
Assert.False(result);
|
|
passwordHasher.DidNotReceive().VerifyHashedPassword(Arg.Any<SendPasswordHasherMarker>(), Arg.Any<string>(), Arg.Any<string>());
|
|
}
|
|
|
|
[Theory, BitAutoData]
|
|
void HashPasswordHash_WithValidInput_ReturnsHashedPassword(
|
|
SutProvider<SendPasswordHasher> sutProvider,
|
|
string clientHashedPassword,
|
|
string expectedHashedResult)
|
|
{
|
|
// Arrange
|
|
sutProvider.GetDependency<IPasswordHasher<SendPasswordHasherMarker>>()
|
|
.HashPassword(Arg.Any<SendPasswordHasherMarker>(), clientHashedPassword)
|
|
.Returns(expectedHashedResult);
|
|
|
|
// Act
|
|
var result = sutProvider.Sut.HashOfClientPasswordHash(clientHashedPassword);
|
|
|
|
// Assert
|
|
Assert.Equal(expectedHashedResult, result);
|
|
sutProvider.GetDependency<IPasswordHasher<SendPasswordHasherMarker>>()
|
|
.Received(1)
|
|
.HashPassword(Arg.Any<SendPasswordHasherMarker>(), clientHashedPassword);
|
|
}
|
|
}
|