Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,15 @@ public EmergencyAccessTakeoverResponseModel(EmergencyAccess emergencyAccess, Use
KdfIterations = grantor.KdfIterations;
KdfMemory = grantor.KdfMemory;
KdfParallelism = grantor.KdfParallelism;
Salt = grantor.GetMasterPasswordSalt();
}

public int KdfIterations { get; private set; }
public int? KdfMemory { get; private set; }
public int? KdfParallelism { get; private set; }
public KdfType Kdf { get; private set; }
public string KeyEncrypted { get; private set; }
public string Salt { get; private set; }
}

public class EmergencyAccessViewResponseModel : ResponseModel
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Entities/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFac
public string? Key { get; set; }
/// <summary>
/// The raw public key, without a signature from the user's signature key.
/// </summary>
/// </summary>
public string? PublicKey { get; set; }
/// <summary>
/// User key wrapped private key.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
๏ปฟusing Bit.Api.Auth.Models.Response;
using Bit.Core.Auth.Entities;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Test.Common.AutoFixture.Attributes;
using Xunit;

namespace Bit.Api.Test.Auth.Models.Response;

public class EmergencyAccessTakeoverResponseModelTests
{
[Theory]
[BitAutoData]
public void Constructor_EmergencyAccessNull_ThrowsArgumentNullException(User grantor)
{
var exception = Assert.Throws<ArgumentNullException>(
() => new EmergencyAccessTakeoverResponseModel(null, grantor));
Assert.Equal("emergencyAccess", exception.ParamName);
}

[Theory]
[BitAutoData]
public void Constructor_ValidInputs_SetsAllPropertiesCorrectly(
EmergencyAccess emergencyAccess, User grantor)
{
var model = new EmergencyAccessTakeoverResponseModel(emergencyAccess, grantor);

Assert.Equal(emergencyAccess.KeyEncrypted, model.KeyEncrypted);
Assert.Equal(grantor.Kdf, model.Kdf);
Assert.Equal(grantor.KdfIterations, model.KdfIterations);
Assert.Equal(grantor.KdfMemory, model.KdfMemory);
Assert.Equal(grantor.KdfParallelism, model.KdfParallelism);
Assert.Equal(grantor.GetMasterPasswordSalt(), model.Salt);
}

[Theory]
[BitAutoData]
public void Constructor_Salt_EqualsGrantorEmailLowercasedAndTrimmed(
EmergencyAccess emergencyAccess, User grantor)
{
grantor.Email = " [email protected] ";

var model = new EmergencyAccessTakeoverResponseModel(emergencyAccess, grantor);

Assert.Equal("[email protected]", model.Salt);
}

[Theory]
[InlineData("[email protected]", "[email protected]")]
[InlineData("[email protected]", "[email protected]")]
[InlineData(" [email protected] ", "[email protected]")]
[InlineData(" [email protected] ", "[email protected]")]
public void Constructor_SaltWithVariousEmailFormats_NormalizesCorrectly(
string email, string expectedSalt)
{
var emergencyAccess = new EmergencyAccess
{
Id = Guid.NewGuid(),
KeyEncrypted = "test-key-encrypted"
};
var grantor = new User
{
Id = Guid.NewGuid(),
Email = email,
SecurityStamp = "security-stamp",
ApiKey = "api-key"
};

var model = new EmergencyAccessTakeoverResponseModel(emergencyAccess, grantor);

Assert.Equal(expectedSalt, model.Salt);
}

[Theory]
[BitAutoData]
public void Constructor_WithPBKDF2_SetsKdfTypeCorrectly(
EmergencyAccess emergencyAccess, User grantor)
{
grantor.Kdf = KdfType.PBKDF2_SHA256;
grantor.KdfIterations = 600000;
grantor.KdfMemory = null;
grantor.KdfParallelism = null;

var model = new EmergencyAccessTakeoverResponseModel(emergencyAccess, grantor);

Assert.Equal(KdfType.PBKDF2_SHA256, model.Kdf);
Assert.Equal(600000, model.KdfIterations);
Assert.Null(model.KdfMemory);
Assert.Null(model.KdfParallelism);
}

[Theory]
[BitAutoData]
public void Constructor_WithArgon2id_SetsAllKdfPropertiesCorrectly(
EmergencyAccess emergencyAccess, User grantor)
{
grantor.Kdf = KdfType.Argon2id;
grantor.KdfIterations = 3;
grantor.KdfMemory = 64;
grantor.KdfParallelism = 4;

var model = new EmergencyAccessTakeoverResponseModel(emergencyAccess, grantor);

Assert.Equal(KdfType.Argon2id, model.Kdf);
Assert.Equal(3, model.KdfIterations);
Assert.Equal(64, model.KdfMemory);
Assert.Equal(4, model.KdfParallelism);
}

[Theory]
[BitAutoData]
public void Constructor_SetsObjectTypeCorrectly(
EmergencyAccess emergencyAccess, User grantor)
{
var model = new EmergencyAccessTakeoverResponseModel(emergencyAccess, grantor);

Assert.Equal("emergencyAccessTakeover", model.Object);
}

[Theory]
[BitAutoData]
public void Constructor_CustomObjectName_SetsObjectTypeCorrectly(
EmergencyAccess emergencyAccess, User grantor)
{
var model = new EmergencyAccessTakeoverResponseModel(emergencyAccess, grantor, "customObject");

Assert.Equal("customObject", model.Object);
}
}
Loading