1
0
mirror of https://github.com/bitwarden/server.git synced 2025-02-12 01:11:22 +01:00
bitwarden-server/test/Infrastructure.IntegrationTest/Vault/Repositories/SecurityTaskRepositoryTests.cs
SmithThe4th a332a69112
[PM-14376] Add GET tasks endpoint (#5089)
* Added CQRS pattern

* Added the GetManyByUserIdAsync signature to the repositiory

* Added sql sproc

Created user defined type to hold status

Created migration file

* Added ef core query

* Added absract and concrete implementation for GetManyByUserIdStatusAsync

* Added integration tests

* Updated params to status

* Implemented new query to utilize repository method

* Added controller for the security task endpoint

* Fixed lint issues

* Added documentation

* simplified to require single status

modified script to check for users with edit rights

* Updated ef core query

* Added new assertions

* simplified to require single status

* fixed formatting

* Fixed sql script

* Removed default null

* Added security tasks feature flag
2024-12-12 14:27:31 -05:00

227 lines
8.1 KiB
C#

using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Enums;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Models.Data;
using Bit.Core.Repositories;
using Bit.Core.Vault.Entities;
using Bit.Core.Vault.Enums;
using Bit.Core.Vault.Repositories;
using Bit.Infrastructure.IntegrationTest.Comparers;
using Xunit;
namespace Bit.Infrastructure.IntegrationTest.Vault.Repositories;
public class SecurityTaskRepositoryTests
{
[DatabaseTheory, DatabaseData]
public async Task CreateAsync(
IOrganizationRepository organizationRepository,
ICipherRepository cipherRepository,
ISecurityTaskRepository securityTaskRepository)
{
var organization = await organizationRepository.CreateAsync(new Organization
{
Name = "Test Org",
PlanType = PlanType.EnterpriseAnnually,
Plan = "Test Plan",
BillingEmail = "billing@email.com"
});
var cipher = await cipherRepository.CreateAsync(new Cipher
{
Type = CipherType.Login,
OrganizationId = organization.Id,
Data = "",
});
var task = await securityTaskRepository.CreateAsync(new SecurityTask
{
OrganizationId = organization.Id,
CipherId = cipher.Id,
Status = SecurityTaskStatus.Pending,
Type = SecurityTaskType.UpdateAtRiskCredential,
});
Assert.NotNull(task);
}
[DatabaseTheory, DatabaseData]
public async Task ReadByIdAsync(
IOrganizationRepository organizationRepository,
ICipherRepository cipherRepository,
ISecurityTaskRepository securityTaskRepository)
{
var organization = await organizationRepository.CreateAsync(new Organization
{
Name = "Test Org",
PlanType = PlanType.EnterpriseAnnually,
Plan = "Test Plan",
BillingEmail = "billing@email.com"
});
var cipher = await cipherRepository.CreateAsync(new Cipher
{
Type = CipherType.Login,
OrganizationId = organization.Id,
Data = "",
});
var task = await securityTaskRepository.CreateAsync(new SecurityTask
{
OrganizationId = organization.Id,
CipherId = cipher.Id,
Status = SecurityTaskStatus.Pending,
Type = SecurityTaskType.UpdateAtRiskCredential,
});
Assert.NotNull(task);
var readTask = await securityTaskRepository.GetByIdAsync(task.Id);
Assert.NotNull(readTask);
Assert.Equal(task.Id, readTask.Id);
Assert.Equal(task.Status, readTask.Status);
}
[DatabaseTheory, DatabaseData]
public async Task UpdateAsync(
IOrganizationRepository organizationRepository,
ICipherRepository cipherRepository,
ISecurityTaskRepository securityTaskRepository)
{
var organization = await organizationRepository.CreateAsync(new Organization
{
Name = "Test Org",
PlanType = PlanType.EnterpriseAnnually,
Plan = "Test Plan",
BillingEmail = "billing@email.com"
});
var cipher = await cipherRepository.CreateAsync(new Cipher
{
Type = CipherType.Login,
OrganizationId = organization.Id,
Data = "",
});
var task = await securityTaskRepository.CreateAsync(new SecurityTask
{
OrganizationId = organization.Id,
CipherId = cipher.Id,
Status = SecurityTaskStatus.Pending,
Type = SecurityTaskType.UpdateAtRiskCredential,
});
Assert.NotNull(task);
task.Status = SecurityTaskStatus.Completed;
await securityTaskRepository.ReplaceAsync(task);
var updatedTask = await securityTaskRepository.GetByIdAsync(task.Id);
Assert.NotNull(updatedTask);
Assert.Equal(task.Id, updatedTask.Id);
Assert.Equal(SecurityTaskStatus.Completed, updatedTask.Status);
}
[DatabaseTheory, DatabaseData]
public async Task GetManyByUserIdAsync_ReturnsExpectedTasks(
IUserRepository userRepository,
IOrganizationRepository organizationRepository,
ICipherRepository cipherRepository,
ISecurityTaskRepository securityTaskRepository,
IOrganizationUserRepository organizationUserRepository,
ICollectionRepository collectionRepository)
{
var user = await userRepository.CreateAsync(new User
{
Name = "Test User",
Email = $"test+{Guid.NewGuid()}@email.com",
ApiKey = "TEST",
SecurityStamp = "stamp",
});
var organization = await organizationRepository.CreateAsync(new Organization
{
Name = "Test Org",
PlanType = PlanType.EnterpriseAnnually,
Plan = "Test Plan",
BillingEmail = "billing@email.com"
});
var orgUser = await organizationUserRepository.CreateAsync(new OrganizationUser
{
OrganizationId = organization.Id,
UserId = user.Id,
Status = OrganizationUserStatusType.Confirmed
});
var collection = await collectionRepository.CreateAsync(new Collection
{
OrganizationId = organization.Id,
Name = "Test Collection 1",
});
var collection2 = await collectionRepository.CreateAsync(new Collection
{
OrganizationId = organization.Id,
Name = "Test Collection 2",
});
var cipher1 = new Cipher { Type = CipherType.Login, OrganizationId = organization.Id, Data = "", };
await cipherRepository.CreateAsync(cipher1, [collection.Id, collection2.Id]);
var cipher2 = new Cipher { Type = CipherType.Login, OrganizationId = organization.Id, Data = "", };
await cipherRepository.CreateAsync(cipher2, [collection.Id]);
var task1 = await securityTaskRepository.CreateAsync(new SecurityTask
{
OrganizationId = organization.Id,
CipherId = cipher1.Id,
Status = SecurityTaskStatus.Pending,
Type = SecurityTaskType.UpdateAtRiskCredential,
});
var task2 = await securityTaskRepository.CreateAsync(new SecurityTask
{
OrganizationId = organization.Id,
CipherId = cipher2.Id,
Status = SecurityTaskStatus.Completed,
Type = SecurityTaskType.UpdateAtRiskCredential,
});
var task3 = await securityTaskRepository.CreateAsync(new SecurityTask
{
OrganizationId = organization.Id,
CipherId = cipher2.Id,
Status = SecurityTaskStatus.Pending,
Type = SecurityTaskType.UpdateAtRiskCredential,
});
await collectionRepository.UpdateUsersAsync(collection.Id,
new List<CollectionAccessSelection>
{
new() {Id = orgUser.Id, ReadOnly = false, HidePasswords = false, Manage = true}
});
var allTasks = await securityTaskRepository.GetManyByUserIdStatusAsync(user.Id);
Assert.Equal(3, allTasks.Count);
Assert.Contains(task1, allTasks, new SecurityTaskComparer());
Assert.Contains(task2, allTasks, new SecurityTaskComparer());
Assert.Contains(task3, allTasks, new SecurityTaskComparer());
var pendingTasks = await securityTaskRepository.GetManyByUserIdStatusAsync(user.Id, SecurityTaskStatus.Pending);
Assert.Equal(2, pendingTasks.Count);
Assert.Contains(task1, pendingTasks, new SecurityTaskComparer());
Assert.Contains(task3, pendingTasks, new SecurityTaskComparer());
Assert.DoesNotContain(task2, pendingTasks, new SecurityTaskComparer());
var completedTasks = await securityTaskRepository.GetManyByUserIdStatusAsync(user.Id, SecurityTaskStatus.Completed);
Assert.Single(completedTasks);
Assert.Contains(task2, completedTasks, new SecurityTaskComparer());
Assert.DoesNotContain(task1, completedTasks, new SecurityTaskComparer());
Assert.DoesNotContain(task3, completedTasks, new SecurityTaskComparer());
}
}