1
0
mirror of https://github.com/bitwarden/server synced 2025-12-12 22:33:45 +00:00
Files
server/test/Api.IntegrationTest/AdminConsole/Controllers/OrganizationUserControllerAutoConfirmTests.cs
Alex Morask f595818ede [PM-24549] Remove feature flag: use-pricing-service (#6567)
* Remove feature flag and move StaticStore plans to MockPlans for tests

* Remove old plan models / move sponsored plans out of StaticStore

* Run dotnet format

* Add pricing URI to Development appsettings for local development and integration tests

* Updated Api Integration tests to get current plan type

* Run dotnet format

* Fix failing tests
2025-11-19 09:53:30 -06:00

226 lines
8.7 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;
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 Bit.Core.Services;
using NSubstitute;
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;
_factory.SubstituteService<IFeatureService>(featureService =>
{
featureService
.IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers)
.Returns(true);
});
_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()}@example.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 tenRequests = Enumerable.Range(0, 10)
.Select(_ => _client.PostAsJsonAsync($"organizations/{organization.Id}/users/{organizationUser.Id}/auto-confirm",
new OrganizationUserConfirmRequestModel
{
Key = testKey,
DefaultUserCollectionName = _mockEncryptedString
})).ToList();
var results = await Task.WhenAll(tenRequests);
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;
}
}