mirror of
https://github.com/bitwarden/server.git
synced 2025-02-13 01:21:29 +01:00
fix(auth): [PM-2996] Add Pending Auth Request Data to Devices Response - New stored procedure to fetch the appropriate data. - Updated devices controller to respond with the new data. - Tests written at the controller and repository level. Resolves PM-2996
192 lines
6.4 KiB
C#
192 lines
6.4 KiB
C#
using Bit.Core.Auth.Entities;
|
|
using Bit.Core.Auth.Enums;
|
|
using Bit.Core.Entities;
|
|
using Bit.Core.Enums;
|
|
using Bit.Core.Repositories;
|
|
using Xunit;
|
|
|
|
namespace Bit.Infrastructure.IntegrationTest.Auth.Repositories;
|
|
|
|
public class DeviceRepositoryTests
|
|
{
|
|
[DatabaseTheory]
|
|
[DatabaseData]
|
|
public async Task GetManyByUserIdWithDeviceAuth_Works_ReturnsExpectedResults(
|
|
IDeviceRepository sutRepository,
|
|
IUserRepository userRepository,
|
|
IAuthRequestRepository authRequestRepository)
|
|
{
|
|
// Arrange
|
|
var user = await userRepository.CreateAsync(new User
|
|
{
|
|
Name = "Test User",
|
|
Email = $"test+{Guid.NewGuid()}@email.com",
|
|
ApiKey = "TEST",
|
|
SecurityStamp = "stamp",
|
|
});
|
|
|
|
var device = await sutRepository.CreateAsync(new Device
|
|
{
|
|
Active = true,
|
|
Name = "chrome-test",
|
|
UserId = user.Id,
|
|
Type = DeviceType.ChromeBrowser,
|
|
Identifier = Guid.NewGuid().ToString(),
|
|
});
|
|
|
|
var staleAuthRequest = await authRequestRepository.CreateAsync(new AuthRequest
|
|
{
|
|
ResponseDeviceId = null,
|
|
Approved = null,
|
|
Type = AuthRequestType.AuthenticateAndUnlock,
|
|
OrganizationId = null,
|
|
UserId = user.Id,
|
|
RequestIpAddress = ":1",
|
|
RequestDeviceIdentifier = device.Identifier,
|
|
AccessCode = "AccessCode_1234",
|
|
PublicKey = "PublicKey_1234"
|
|
});
|
|
staleAuthRequest.CreationDate = DateTime.UtcNow.AddMinutes(-10);
|
|
await authRequestRepository.ReplaceAsync(staleAuthRequest);
|
|
|
|
var freshAuthRequest = await authRequestRepository.CreateAsync(new AuthRequest
|
|
{
|
|
ResponseDeviceId = null,
|
|
Approved = null,
|
|
Type = AuthRequestType.AuthenticateAndUnlock,
|
|
OrganizationId = null,
|
|
UserId = user.Id,
|
|
RequestIpAddress = ":1",
|
|
RequestDeviceIdentifier = device.Identifier,
|
|
AccessCode = "AccessCode_1234",
|
|
PublicKey = "PublicKey_1234",
|
|
Key = "Key_1234",
|
|
MasterPasswordHash = "MasterPasswordHash_1234"
|
|
});
|
|
|
|
// Act
|
|
var response = await sutRepository.GetManyByUserIdWithDeviceAuth(user.Id);
|
|
|
|
// Assert
|
|
Assert.NotNull(response.First().AuthRequestId);
|
|
Assert.NotNull(response.First().AuthRequestCreatedAt);
|
|
Assert.Equal(response.First().AuthRequestId, freshAuthRequest.Id);
|
|
}
|
|
|
|
[DatabaseTheory]
|
|
[DatabaseData]
|
|
public async Task GetManyByUserIdWithDeviceAuth_WorksWithNoAuthRequestAndMultipleDevices_ReturnsExpectedResults(
|
|
IDeviceRepository sutRepository,
|
|
IUserRepository userRepository)
|
|
{
|
|
// Arrange
|
|
var user = await userRepository.CreateAsync(new User
|
|
{
|
|
Name = "Test User",
|
|
Email = $"test+{Guid.NewGuid()}@email.com",
|
|
ApiKey = "TEST",
|
|
SecurityStamp = "stamp",
|
|
});
|
|
|
|
await sutRepository.CreateAsync(new Device
|
|
{
|
|
Active = true,
|
|
Name = "chrome-test",
|
|
UserId = user.Id,
|
|
Type = DeviceType.ChromeBrowser,
|
|
Identifier = Guid.NewGuid().ToString(),
|
|
});
|
|
|
|
await sutRepository.CreateAsync(new Device
|
|
{
|
|
Active = true,
|
|
Name = "macos-test",
|
|
UserId = user.Id,
|
|
Type = DeviceType.MacOsDesktop,
|
|
Identifier = Guid.NewGuid().ToString(),
|
|
});
|
|
|
|
// Act
|
|
var response = await sutRepository.GetManyByUserIdWithDeviceAuth(user.Id);
|
|
|
|
// Assert
|
|
Assert.NotNull(response.First());
|
|
Assert.Null(response.First().AuthRequestId);
|
|
Assert.True(response.Count == 2);
|
|
}
|
|
|
|
[DatabaseTheory]
|
|
[DatabaseData]
|
|
public async Task GetManyByUserIdWithDeviceAuth_FailsToRespondWithAnyAuthData_ReturnsExpectedResults(
|
|
IDeviceRepository sutRepository,
|
|
IUserRepository userRepository,
|
|
IAuthRequestRepository authRequestRepository)
|
|
{
|
|
var casesThatCauseNoAuthDataInResponse = new[]
|
|
{
|
|
new
|
|
{
|
|
authRequestType = AuthRequestType.AdminApproval, // Device typing is wrong
|
|
authRequestApproved = (bool?)null,
|
|
expirey = DateTime.UtcNow.AddMinutes(0),
|
|
},
|
|
new
|
|
{
|
|
authRequestType = AuthRequestType.AuthenticateAndUnlock,
|
|
authRequestApproved = (bool?)true, // Auth request is already approved
|
|
expirey = DateTime.UtcNow.AddMinutes(0),
|
|
},
|
|
new
|
|
{
|
|
authRequestType = AuthRequestType.AuthenticateAndUnlock,
|
|
authRequestApproved = (bool?)null,
|
|
expirey = DateTime.UtcNow.AddMinutes(-30), // Past the point of expiring
|
|
}
|
|
};
|
|
|
|
foreach (var testCase in casesThatCauseNoAuthDataInResponse)
|
|
{
|
|
// Arrange
|
|
var user = await userRepository.CreateAsync(new User
|
|
{
|
|
Name = "Test User",
|
|
Email = $"test+{Guid.NewGuid()}@email.com",
|
|
ApiKey = "TEST",
|
|
SecurityStamp = "stamp",
|
|
});
|
|
|
|
var device = await sutRepository.CreateAsync(new Device
|
|
{
|
|
Active = true,
|
|
Name = "chrome-test",
|
|
UserId = user.Id,
|
|
Type = DeviceType.ChromeBrowser,
|
|
Identifier = Guid.NewGuid().ToString(),
|
|
});
|
|
|
|
var authRequest = await authRequestRepository.CreateAsync(new AuthRequest
|
|
{
|
|
ResponseDeviceId = null,
|
|
Approved = testCase.authRequestApproved,
|
|
Type = testCase.authRequestType,
|
|
OrganizationId = null,
|
|
UserId = user.Id,
|
|
RequestIpAddress = ":1",
|
|
RequestDeviceIdentifier = device.Identifier,
|
|
AccessCode = "AccessCode_1234",
|
|
PublicKey = "PublicKey_1234"
|
|
});
|
|
|
|
authRequest.CreationDate = testCase.expirey;
|
|
await authRequestRepository.ReplaceAsync(authRequest);
|
|
|
|
// Act
|
|
var response = await sutRepository.GetManyByUserIdWithDeviceAuth(user.Id);
|
|
|
|
// Assert
|
|
Assert.Null(response.First().AuthRequestId);
|
|
Assert.Null(response.First().AuthRequestCreatedAt);
|
|
}
|
|
}
|
|
}
|