mirror of
https://github.com/bitwarden/server.git
synced 2026-04-10 09:41:16 -05:00
* Refactor organization user confirmation logic by removing direct feature flag checks. Updated related commands and tests to utilize policy requirements instead of feature service checks for automatic user confirmation. Cleaned up organization form view by simplifying checkbox rendering for automatic user confirmation. * Refactor ProviderService to remove feature service dependency for automatic user confirmation. Updated logic to streamline policy requirement checks and cleaned up related tests by removing unnecessary feature flag assertions. * Enhance tests for automatic user confirmation policy requirements. Updated multiple test classes to include checks for `AutomaticUserConfirmationPolicyRequirement`, ensuring no auto-confirm restrictions are applied by default. Refactored related assertions in `AcceptOrgUserCommandTests`, `ConfirmOrganizationUserCommandTests`, `RestoreOrganizationUserCommandTests`, and others to streamline compliance validation logic. * Enhance tests for automatic user confirmation policy across multiple test classes. Added checks for `AutomaticUserConfirmationPolicyRequirement` in `ConfirmOrganizationUserCommandTests`, `RestoreOrganizationUserCommandTests`, and `SelfHostedOrganizationSignUpCommandTests`, ensuring compliance validation logic is streamlined and consistent. Updated assertions to reflect new policy requirements. * Implement mock for AutomaticUserConfirmationPolicyRequirement in ProviderServiceTests to enhance test coverage for user confirmation policies. * Update ProviderServiceTests to include mocks for AutomaticUserConfirmationPolicyRequirement, enhancing test coverage for user acceptance scenarios. * Refactor test method names in EmergencyAccessServiceTests for clarity by removing feature flag references, improving readability and maintainability of the test suite.
219 lines
8.4 KiB
C#
219 lines
8.4 KiB
C#
using System.Net;
|
|
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
|
using Bit.Api.IntegrationTest.Factories;
|
|
using Bit.Api.IntegrationTest.Helpers;
|
|
using Bit.Core.AdminConsole.Entities;
|
|
using Bit.Core.AdminConsole.Enums;
|
|
using Bit.Core.AdminConsole.Repositories;
|
|
using Bit.Core.Billing.Enums;
|
|
using Bit.Core.Enums;
|
|
using Bit.Core.Models.Data;
|
|
using Bit.Core.Repositories;
|
|
using Xunit;
|
|
|
|
namespace Bit.Api.IntegrationTest.AdminConsole.Controllers;
|
|
|
|
public class OrganizationUserControllerAutoConfirmTests : IClassFixture<ApiApplicationFactory>, IAsyncLifetime
|
|
{
|
|
private const string _mockEncryptedString = "2.AOs41Hd8OQiCPXjyJKCiDA==|O6OHgt2U2hJGBSNGnimJmg==|iD33s8B69C8JhYYhSa4V1tArjvLr8eEaGqOV7BRo5Jk=";
|
|
|
|
private readonly HttpClient _client;
|
|
private readonly ApiApplicationFactory _factory;
|
|
private readonly LoginHelper _loginHelper;
|
|
|
|
private string _ownerEmail = null!;
|
|
|
|
public OrganizationUserControllerAutoConfirmTests(ApiApplicationFactory apiFactory)
|
|
{
|
|
_factory = apiFactory;
|
|
_client = _factory.CreateClient();
|
|
_loginHelper = new LoginHelper(_factory, _client);
|
|
}
|
|
|
|
public async Task InitializeAsync()
|
|
{
|
|
_ownerEmail = $"org-owner-{Guid.NewGuid()}@example.com";
|
|
await _factory.LoginWithNewAccount(_ownerEmail);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task AutoConfirm_WhenUserCannotManageOtherUsers_ThenShouldReturnForbidden()
|
|
{
|
|
var (organization, _) = await OrganizationTestHelpers.SignUpAsync(_factory, plan: PlanType.EnterpriseAnnually,
|
|
ownerEmail: _ownerEmail, passwordManagerSeats: 5, paymentMethod: PaymentMethodType.Card);
|
|
|
|
organization.UseAutomaticUserConfirmation = true;
|
|
|
|
await _factory.GetService<IOrganizationRepository>()
|
|
.UpsertAsync(organization);
|
|
|
|
var testKey = $"test-key-{Guid.NewGuid()}";
|
|
|
|
var userToConfirmEmail = $"org-user-to-confirm-{Guid.NewGuid()}@example.com";
|
|
await _factory.LoginWithNewAccount(userToConfirmEmail);
|
|
|
|
var (confirmingUserEmail, _) = await OrganizationTestHelpers.CreateNewUserWithAccountAsync(_factory, organization.Id, OrganizationUserType.User);
|
|
await _loginHelper.LoginAsync(confirmingUserEmail);
|
|
|
|
var organizationUser = await OrganizationTestHelpers.CreateUserAsync(
|
|
_factory,
|
|
organization.Id,
|
|
userToConfirmEmail,
|
|
OrganizationUserType.User,
|
|
false,
|
|
new Permissions { ManageUsers = false },
|
|
OrganizationUserStatusType.Accepted);
|
|
|
|
var result = await _client.PostAsJsonAsync($"organizations/{organization.Id}/users/{organizationUser.Id}/auto-confirm",
|
|
new OrganizationUserConfirmRequestModel
|
|
{
|
|
Key = testKey,
|
|
DefaultUserCollectionName = _mockEncryptedString
|
|
});
|
|
|
|
Assert.Equal(HttpStatusCode.Forbidden, result.StatusCode);
|
|
|
|
await _factory.GetService<IOrganizationRepository>().DeleteAsync(organization);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task AutoConfirm_WhenOwnerConfirmsValidUser_ThenShouldReturnNoContent()
|
|
{
|
|
var (organization, _) = await OrganizationTestHelpers.SignUpAsync(_factory, plan: PlanType.EnterpriseAnnually,
|
|
ownerEmail: _ownerEmail, passwordManagerSeats: 5, paymentMethod: PaymentMethodType.Card);
|
|
|
|
organization.UseAutomaticUserConfirmation = true;
|
|
|
|
await _factory.GetService<IOrganizationRepository>()
|
|
.UpsertAsync(organization);
|
|
|
|
var testKey = $"test-key-{Guid.NewGuid()}";
|
|
|
|
await _factory.GetService<IPolicyRepository>().CreateAsync(new Policy
|
|
{
|
|
OrganizationId = organization.Id,
|
|
Type = PolicyType.AutomaticUserConfirmation,
|
|
Enabled = true
|
|
});
|
|
|
|
await _factory.GetService<IPolicyRepository>().CreateAsync(new Policy
|
|
{
|
|
OrganizationId = organization.Id,
|
|
Type = PolicyType.OrganizationDataOwnership,
|
|
Enabled = true
|
|
});
|
|
|
|
var userToConfirmEmail = $"org-user-to-confirm-{Guid.NewGuid()}@example.com";
|
|
await _factory.LoginWithNewAccount(userToConfirmEmail);
|
|
|
|
await _loginHelper.LoginAsync(_ownerEmail);
|
|
var organizationUser = await OrganizationTestHelpers.CreateUserAsync(
|
|
_factory,
|
|
organization.Id,
|
|
userToConfirmEmail,
|
|
OrganizationUserType.User,
|
|
false,
|
|
new Permissions(),
|
|
OrganizationUserStatusType.Accepted);
|
|
|
|
var result = await _client.PostAsJsonAsync($"organizations/{organization.Id}/users/{organizationUser.Id}/auto-confirm",
|
|
new OrganizationUserConfirmRequestModel
|
|
{
|
|
Key = testKey,
|
|
DefaultUserCollectionName = _mockEncryptedString
|
|
});
|
|
|
|
Assert.Equal(HttpStatusCode.NoContent, result.StatusCode);
|
|
|
|
var orgUserRepository = _factory.GetService<IOrganizationUserRepository>();
|
|
var confirmedUser = await orgUserRepository.GetByIdAsync(organizationUser.Id);
|
|
Assert.NotNull(confirmedUser);
|
|
Assert.Equal(OrganizationUserStatusType.Confirmed, confirmedUser.Status);
|
|
Assert.Equal(testKey, confirmedUser.Key);
|
|
|
|
var collectionRepository = _factory.GetService<ICollectionRepository>();
|
|
var collections = await collectionRepository.GetManyByUserIdAsync(organizationUser.UserId!.Value);
|
|
|
|
Assert.NotEmpty(collections);
|
|
Assert.Single(collections.Where(c => c.Type == CollectionType.DefaultUserCollection));
|
|
|
|
await _factory.GetService<IOrganizationRepository>().DeleteAsync(organization);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task AutoConfirm_WhenUserIsConfirmedMultipleTimes_ThenShouldSuccessAndOnlyConfirmOneUser()
|
|
{
|
|
var (organization, _) = await OrganizationTestHelpers.SignUpAsync(_factory, plan: PlanType.EnterpriseAnnually,
|
|
ownerEmail: _ownerEmail, passwordManagerSeats: 5, paymentMethod: PaymentMethodType.Card);
|
|
|
|
organization.UseAutomaticUserConfirmation = true;
|
|
|
|
await _factory.GetService<IOrganizationRepository>()
|
|
.UpsertAsync(organization);
|
|
|
|
var testKey = $"test-key-{Guid.NewGuid()}";
|
|
|
|
var userToConfirmEmail = $"org-user-to-confirm-{Guid.NewGuid()}@bitwarden.com";
|
|
await _factory.LoginWithNewAccount(userToConfirmEmail);
|
|
|
|
await _factory.GetService<IPolicyRepository>().CreateAsync(new Policy
|
|
{
|
|
OrganizationId = organization.Id,
|
|
Type = PolicyType.AutomaticUserConfirmation,
|
|
Enabled = true
|
|
});
|
|
|
|
await _factory.GetService<IPolicyRepository>().CreateAsync(new Policy
|
|
{
|
|
OrganizationId = organization.Id,
|
|
Type = PolicyType.OrganizationDataOwnership,
|
|
Enabled = true
|
|
});
|
|
|
|
await _loginHelper.LoginAsync(_ownerEmail);
|
|
|
|
var organizationUser = await OrganizationTestHelpers.CreateUserAsync(
|
|
_factory,
|
|
organization.Id,
|
|
userToConfirmEmail,
|
|
OrganizationUserType.User,
|
|
false,
|
|
new Permissions(),
|
|
OrganizationUserStatusType.Accepted);
|
|
|
|
var results = new List<HttpResponseMessage>();
|
|
|
|
foreach (var _ in Enumerable.Range(0, 10))
|
|
{
|
|
results.Add(await _client.PostAsJsonAsync($"organizations/{organization.Id}/users/{organizationUser.Id}/auto-confirm",
|
|
new OrganizationUserConfirmRequestModel
|
|
{
|
|
Key = testKey,
|
|
DefaultUserCollectionName = _mockEncryptedString
|
|
}));
|
|
}
|
|
|
|
Assert.Contains(results, r => r.StatusCode == HttpStatusCode.NoContent);
|
|
|
|
var orgUserRepository = _factory.GetService<IOrganizationUserRepository>();
|
|
var confirmedUser = await orgUserRepository.GetByIdAsync(organizationUser.Id);
|
|
Assert.NotNull(confirmedUser);
|
|
Assert.Equal(OrganizationUserStatusType.Confirmed, confirmedUser.Status);
|
|
Assert.Equal(testKey, confirmedUser.Key);
|
|
|
|
var collections = await _factory.GetService<ICollectionRepository>()
|
|
.GetManyByUserIdAsync(organizationUser.UserId!.Value);
|
|
Assert.NotEmpty(collections);
|
|
// validates user only received one default collection
|
|
Assert.Single(collections.Where(c => c.Type == CollectionType.DefaultUserCollection));
|
|
|
|
await _factory.GetService<IOrganizationRepository>().DeleteAsync(organization);
|
|
}
|
|
|
|
public Task DisposeAsync()
|
|
{
|
|
_client.Dispose();
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|