mirror of
https://github.com/bitwarden/server.git
synced 2025-06-27 22:26:13 -05:00
add api integration tests for users WIP
This commit is contained in:
parent
bab0429adf
commit
c11cef2bf2
@ -54,25 +54,26 @@ public class OrganizationController : Controller
|
|||||||
throw new BadRequestException("You cannot import this much data at once.");
|
throw new BadRequestException("You cannot import this much data at once.");
|
||||||
}
|
}
|
||||||
|
|
||||||
string r = "";
|
if (_featureService.IsEnabled(FeatureFlagKeys.ImportAsyncRefactor))
|
||||||
|
{
|
||||||
r = await _importOrganizationUsersAndGroupsCommand.ImportAsync(
|
await _importOrganizationUsersAndGroupsCommand.ImportAsync(
|
||||||
_currentContext.OrganizationId.Value,
|
_currentContext.OrganizationId.Value,
|
||||||
model.Groups.Select(g => g.ToImportedGroup(_currentContext.OrganizationId.Value)),
|
model.Groups.Select(g => g.ToImportedGroup(_currentContext.OrganizationId.Value)),
|
||||||
model.Members.Where(u => !u.Deleted).Select(u => u.ToImportedOrganizationUser()),
|
model.Members.Where(u => !u.Deleted).Select(u => u.ToImportedOrganizationUser()),
|
||||||
model.Members.Where(u => u.Deleted).Select(u => u.ExternalId),
|
model.Members.Where(u => u.Deleted).Select(u => u.ExternalId),
|
||||||
model.OverwriteExisting.GetValueOrDefault());
|
model.OverwriteExisting.GetValueOrDefault());
|
||||||
|
|
||||||
|
|
||||||
if (_featureService.IsEnabled(FeatureFlagKeys.ImportAsyncRefactor))
|
|
||||||
{
|
|
||||||
r = "success";
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
r = "fail";
|
await _organizationService.ImportAsync(
|
||||||
|
_currentContext.OrganizationId.Value,
|
||||||
|
model.Groups.Select(g => g.ToImportedGroup(_currentContext.OrganizationId.Value)),
|
||||||
|
model.Members.Where(u => !u.Deleted).Select(u => u.ToImportedOrganizationUser()),
|
||||||
|
model.Members.Where(u => u.Deleted).Select(u => u.ExternalId),
|
||||||
|
model.OverwriteExisting.GetValueOrDefault(),
|
||||||
|
Core.Enums.EventSystemUser.PublicApi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new OkObjectResult(r);
|
return new OkResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interface
|
|||||||
|
|
||||||
public interface IImportOrganizationUsersAndGroupsCommand
|
public interface IImportOrganizationUsersAndGroupsCommand
|
||||||
{
|
{
|
||||||
Task<string> ImportAsync(Guid organizationId,
|
Task ImportAsync(Guid organizationId,
|
||||||
IEnumerable<ImportedGroup> groups,
|
IEnumerable<ImportedGroup> groups,
|
||||||
IEnumerable<ImportedOrganizationUser> newUsers,
|
IEnumerable<ImportedOrganizationUser> newUsers,
|
||||||
IEnumerable<string> removeUserExternalIds,
|
IEnumerable<string> removeUserExternalIds,
|
||||||
|
@ -66,7 +66,7 @@ public class ImportOrganizationUsersAndGroupsCommand : IImportOrganizationUsersA
|
|||||||
/// who are not included in the current import.</param>
|
/// who are not included in the current import.</param>
|
||||||
/// <exception cref="NotFoundException">Thrown if the organization does not exist.</exception>
|
/// <exception cref="NotFoundException">Thrown if the organization does not exist.</exception>
|
||||||
/// <exception cref="BadRequestException">Thrown if the organization is not configured to use directory syncing.</exception>
|
/// <exception cref="BadRequestException">Thrown if the organization is not configured to use directory syncing.</exception>
|
||||||
public async Task<string> ImportAsync(Guid organizationId,
|
public async Task ImportAsync(Guid organizationId,
|
||||||
IEnumerable<ImportedGroup> importedGroups,
|
IEnumerable<ImportedGroup> importedGroups,
|
||||||
IEnumerable<ImportedOrganizationUser> importedUsers,
|
IEnumerable<ImportedOrganizationUser> importedUsers,
|
||||||
IEnumerable<string> removeUserExternalIds,
|
IEnumerable<string> removeUserExternalIds,
|
||||||
@ -101,8 +101,6 @@ public class ImportOrganizationUsersAndGroupsCommand : IImportOrganizationUsersA
|
|||||||
await ImportGroups(organization, importedGroups, importUserData);
|
await ImportGroups(organization, importedGroups, importUserData);
|
||||||
|
|
||||||
await _eventService.LogOrganizationUserEventsAsync(events.Select(e => (e.ou, e.e, _EventSystemUser, e.d)));
|
await _eventService.LogOrganizationUserEventsAsync(events.Select(e => (e.ou, e.e, _EventSystemUser, e.d)));
|
||||||
|
|
||||||
return "success";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
using Bit.Api.AdminConsole.Public.Models.Request;
|
using System.Net;
|
||||||
|
using Bit.Api.AdminConsole.Public.Models.Request;
|
||||||
using Bit.Api.IntegrationTest.Factories;
|
using Bit.Api.IntegrationTest.Factories;
|
||||||
using Bit.Api.IntegrationTest.Helpers;
|
using Bit.Api.IntegrationTest.Helpers;
|
||||||
|
using Bit.Core;
|
||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.Billing.Enums;
|
using Bit.Core.Billing.Enums;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
|
using NSubstitute;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Bit.Api.IntegrationTest.AdminConsole.Import;
|
||||||
|
|
||||||
public class ImportOrganizationUsersAndGroupsCommandTests : IClassFixture<ApiApplicationFactory>, IAsyncLifetime
|
public class ImportOrganizationUsersAndGroupsCommandTests : IClassFixture<ApiApplicationFactory>, IAsyncLifetime
|
||||||
{
|
{
|
||||||
private readonly HttpClient _client;
|
private readonly HttpClient _client;
|
||||||
@ -17,8 +24,9 @@ public class ImportOrganizationUsersAndGroupsCommandTests : IClassFixture<ApiApp
|
|||||||
public ImportOrganizationUsersAndGroupsCommandTests(ApiApplicationFactory factory)
|
public ImportOrganizationUsersAndGroupsCommandTests(ApiApplicationFactory factory)
|
||||||
{
|
{
|
||||||
_factory = factory;
|
_factory = factory;
|
||||||
_factory.UpdateConfiguration("globalSettings:launchDarkly:flagValues:pm-22583-refactor-import-async",
|
_factory.SubstituteService((IFeatureService featureService)
|
||||||
"true");
|
=> featureService.IsEnabled(FeatureFlagKeys.ImportAsyncRefactor)
|
||||||
|
.Returns(true));
|
||||||
_client = _factory.CreateClient();
|
_client = _factory.CreateClient();
|
||||||
_loginHelper = new LoginHelper(_factory, _client);
|
_loginHelper = new LoginHelper(_factory, _client);
|
||||||
}
|
}
|
||||||
@ -44,11 +52,12 @@ public class ImportOrganizationUsersAndGroupsCommandTests : IClassFixture<ApiApp
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Import_Existing_User_Success()
|
public async Task Import_Existing_Organization_User_Succeeds()
|
||||||
{
|
{
|
||||||
var (email, orgUser) = await OrganizationTestHelpers.CreateNewUserWithAccountAsync(_factory, _organization.Id,
|
var (email, ou) = await OrganizationTestHelpers.CreateNewUserWithAccountAsync(_factory, _organization.Id,
|
||||||
OrganizationUserType.User);
|
OrganizationUserType.User);
|
||||||
|
|
||||||
|
var externalId = Guid.NewGuid().ToString();
|
||||||
var request = new OrganizationImportRequestModel();
|
var request = new OrganizationImportRequestModel();
|
||||||
request.LargeImport = false;
|
request.LargeImport = false;
|
||||||
request.OverwriteExisting = false;
|
request.OverwriteExisting = false;
|
||||||
@ -57,16 +66,117 @@ public class ImportOrganizationUsersAndGroupsCommandTests : IClassFixture<ApiApp
|
|||||||
new OrganizationImportRequestModel.OrganizationImportMemberRequestModel
|
new OrganizationImportRequestModel.OrganizationImportMemberRequestModel
|
||||||
{
|
{
|
||||||
Email = email,
|
Email = email,
|
||||||
ExternalId = Guid.NewGuid().ToString(),
|
ExternalId = externalId,
|
||||||
Deleted = false
|
Deleted = false
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
var response = await _client.PostAsync($"/public/organization/import", JsonContent.Create(request));
|
var response = await _client.PostAsync($"/public/organization/import", JsonContent.Create(request));
|
||||||
var result = await response.Content.ReadAsStringAsync();
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
Assert.Equal("success", result);
|
// Assert against the database values
|
||||||
//Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
var organizationUserRepository = _factory.GetService<IOrganizationUserRepository>();
|
||||||
|
var orgUser = await organizationUserRepository.GetByIdAsync(ou.Id);
|
||||||
|
|
||||||
|
Assert.NotNull(orgUser);
|
||||||
|
Assert.Equal(ou.Id, orgUser.Id);
|
||||||
|
Assert.Equal(email, orgUser.Email);
|
||||||
|
Assert.Equal(OrganizationUserType.User, orgUser.Type);
|
||||||
|
Assert.Equal(externalId, orgUser.ExternalId);
|
||||||
|
Assert.Equal(OrganizationUserStatusType.Confirmed, orgUser.Status);
|
||||||
|
Assert.Equal(_organization.Id, orgUser.OrganizationId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Import_New_Organization_User_Succeeds()
|
||||||
|
{
|
||||||
|
var email = $"integration-test{Guid.NewGuid()}@bitwarden.com";
|
||||||
|
await _factory.LoginWithNewAccount(email);
|
||||||
|
|
||||||
|
var externalId = Guid.NewGuid().ToString();
|
||||||
|
var request = new OrganizationImportRequestModel();
|
||||||
|
request.LargeImport = false;
|
||||||
|
request.OverwriteExisting = false;
|
||||||
|
request.Groups = [];
|
||||||
|
request.Members = [
|
||||||
|
new OrganizationImportRequestModel.OrganizationImportMemberRequestModel
|
||||||
|
{
|
||||||
|
Email = email,
|
||||||
|
ExternalId = externalId,
|
||||||
|
Deleted = false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
var response = await _client.PostAsync($"/public/organization/import", JsonContent.Create(request));
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
// Assert against the database values
|
||||||
|
var organizationUserRepository = _factory.GetService<IOrganizationUserRepository>();
|
||||||
|
var orgUser = await organizationUserRepository.GetByOrganizationEmailAsync(_organization.Id, email);
|
||||||
|
|
||||||
|
Assert.NotNull(orgUser);
|
||||||
|
Assert.Equal(email, orgUser.Email);
|
||||||
|
Assert.Equal(OrganizationUserType.User, orgUser.Type);
|
||||||
|
Assert.Equal(externalId, orgUser.ExternalId);
|
||||||
|
Assert.Equal(OrganizationUserStatusType.Invited, orgUser.Status);
|
||||||
|
Assert.Equal(_organization.Id, orgUser.OrganizationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Import_New_And_Existing_Organization_Users_Succeeds()
|
||||||
|
{
|
||||||
|
// Existing organization user
|
||||||
|
var (existingEmail, ou) = await OrganizationTestHelpers.CreateNewUserWithAccountAsync(_factory, _organization.Id,
|
||||||
|
OrganizationUserType.User);
|
||||||
|
var existingExternalId = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
// New organization user
|
||||||
|
var newEmail = $"integration-test{Guid.NewGuid()}@bitwarden.com";
|
||||||
|
await _factory.LoginWithNewAccount(newEmail);
|
||||||
|
var newExternalId = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
var request = new OrganizationImportRequestModel();
|
||||||
|
request.LargeImport = false;
|
||||||
|
request.OverwriteExisting = false;
|
||||||
|
request.Groups = [];
|
||||||
|
request.Members = [
|
||||||
|
new OrganizationImportRequestModel.OrganizationImportMemberRequestModel
|
||||||
|
{
|
||||||
|
Email = existingEmail,
|
||||||
|
ExternalId = existingExternalId,
|
||||||
|
Deleted = false
|
||||||
|
},
|
||||||
|
new OrganizationImportRequestModel.OrganizationImportMemberRequestModel
|
||||||
|
{
|
||||||
|
Email = newEmail,
|
||||||
|
ExternalId = newExternalId,
|
||||||
|
Deleted = false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
var response = await _client.PostAsync($"/public/organization/import", JsonContent.Create(request));
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
// Assert against the database values
|
||||||
|
var organizationUserRepository = _factory.GetService<IOrganizationUserRepository>();
|
||||||
|
|
||||||
|
// Existing user
|
||||||
|
var existingOrgUser = await organizationUserRepository.GetByIdAsync(ou.Id);
|
||||||
|
Assert.NotNull(existingOrgUser);
|
||||||
|
Assert.Equal(existingEmail, existingOrgUser.Email);
|
||||||
|
Assert.Equal(OrganizationUserType.User, existingOrgUser.Type);
|
||||||
|
Assert.Equal(existingExternalId, existingOrgUser.ExternalId);
|
||||||
|
Assert.Equal(OrganizationUserStatusType.Confirmed, existingOrgUser.Status);
|
||||||
|
Assert.Equal(_organization.Id, existingOrgUser.OrganizationId);
|
||||||
|
|
||||||
|
// New User
|
||||||
|
var newOrgUser = await organizationUserRepository.GetByOrganizationEmailAsync(_organization.Id, newEmail);
|
||||||
|
Assert.NotNull(newOrgUser);
|
||||||
|
Assert.Equal(newEmail, newOrgUser.Email);
|
||||||
|
Assert.Equal(OrganizationUserType.User, newOrgUser.Type);
|
||||||
|
Assert.Equal(newExternalId, newOrgUser.ExternalId);
|
||||||
|
Assert.Equal(OrganizationUserStatusType.Invited, newOrgUser.Status);
|
||||||
|
Assert.Equal(_organization.Id, newOrgUser.OrganizationId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@ public static class OrganizationTestHelpers
|
|||||||
Status = userStatusType,
|
Status = userStatusType,
|
||||||
ExternalId = null,
|
ExternalId = null,
|
||||||
AccessSecretsManager = accessSecretsManager,
|
AccessSecretsManager = accessSecretsManager,
|
||||||
|
Email = userEmail
|
||||||
};
|
};
|
||||||
|
|
||||||
if (permissions != null)
|
if (permissions != null)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user