1
0
mirror of https://github.com/bitwarden/server.git synced 2024-12-03 14:03:33 +01:00

Add feature flag

This commit is contained in:
Brandon 2024-11-22 10:20:34 -05:00
parent 56d03b8e5c
commit c4f8679270
No known key found for this signature in database
GPG Key ID: A0E0EF0B207BA40D
2 changed files with 91 additions and 5 deletions

View File

@ -19,6 +19,7 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz
private readonly IUserRepository _userRepository;
private readonly ICurrentContext _currentContext;
private readonly IHasConfirmedOwnersExceptQuery _hasConfirmedOwnersExceptQuery;
private readonly IFeatureService _featureService;
public DeleteManagedOrganizationUserAccountCommand(
IUserService userService,
@ -27,7 +28,8 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz
IOrganizationUserRepository organizationUserRepository,
IUserRepository userRepository,
ICurrentContext currentContext,
IHasConfirmedOwnersExceptQuery hasConfirmedOwnersExceptQuery)
IHasConfirmedOwnersExceptQuery hasConfirmedOwnersExceptQuery,
IFeatureService featureService)
{
_userService = userService;
_eventService = eventService;
@ -36,6 +38,7 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz
_userRepository = userRepository;
_currentContext = currentContext;
_hasConfirmedOwnersExceptQuery = hasConfirmedOwnersExceptQuery;
_featureService = featureService;
}
public async Task DeleteUserAsync(Guid organizationId, Guid organizationUserId, Guid? deletingUserId)
@ -71,6 +74,7 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz
var hasOtherConfirmedOwners = await _hasConfirmedOwnersExceptQuery.HasConfirmedOwnersExceptAsync(organizationId, orgUserIds, includeProvider: true);
var results = new List<(Guid OrganizationUserId, string? ErrorMessage)>();
var accountDeprovisioningEnabled = _featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning);
foreach (var orgUserId in orgUserIds)
{
try
@ -88,7 +92,10 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz
{
throw new NotFoundException("Member not found.");
}
if (!accountDeprovisioningEnabled)
{
await _userService.DeleteAsync(user);
}
results.Add((orgUserId, string.Empty));
}
catch (Exception ex)
@ -97,7 +104,10 @@ public class DeleteManagedOrganizationUserAccountCommand : IDeleteManagedOrganiz
}
}
await _userService.DeleteManyAsync(users);
if (accountDeprovisioningEnabled)
{
await _userService.DeleteManyAsync(users);
}
await LogDeletedOrganizationUsersAsync(orgUsers, results);
return results;

View File

@ -235,7 +235,7 @@ public class DeleteManagedOrganizationUserAccountCommandTests
[Theory]
[BitAutoData]
public async Task DeleteManyUsersAsync_WithValidUsers_DeletesUsersAndLogsEvents(
public async Task DeleteManyUsersAsync_WhenFeatureFlagEnabled_WithValidUsers_DeletesUsersAndLogsEvents(
SutProvider<DeleteManagedOrganizationUserAccountCommand> sutProvider, User user1, User user2, Guid organizationId,
[OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.User)] OrganizationUser orgUser1,
[OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.User)] OrganizationUser orgUser2)
@ -257,6 +257,9 @@ public class DeleteManagedOrganizationUserAccountCommandTests
.GetUsersOrganizationManagementStatusAsync(organizationId, Arg.Any<IEnumerable<Guid>>())
.Returns(new Dictionary<Guid, bool> { { orgUser1.Id, true }, { orgUser2.Id, true } });
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true);
// Act
var userIds = new[] { orgUser1.Id, orgUser2.Id };
var results = await sutProvider.Sut.DeleteManyUsersAsync(organizationId, userIds, null);
@ -267,6 +270,7 @@ public class DeleteManagedOrganizationUserAccountCommandTests
await sutProvider.GetDependency<IOrganizationUserRepository>().Received(1).GetManyAsync(userIds);
await sutProvider.GetDependency<IUserService>().Received(1).DeleteManyAsync(Arg.Any<IEnumerable<User>>());
await sutProvider.GetDependency<IUserService>().Received(0).DeleteAsync(Arg.Any<User>());
await sutProvider.GetDependency<IEventService>().Received(1).LogOrganizationUserEventsAsync(
Arg.Is<IEnumerable<(OrganizationUser, EventType, DateTime?)>>(events =>
events.Count(e => e.Item1.Id == orgUser1.Id && e.Item2 == EventType.OrganizationUser_Deleted) == 1
@ -275,11 +279,59 @@ public class DeleteManagedOrganizationUserAccountCommandTests
[Theory]
[BitAutoData]
public async Task DeleteManyUsersAsync_WhenUserNotFound_ReturnsErrorMessage(
public async Task DeleteManyUsersAsync_WhenFeatureFlagDisabled_WithValidUsers_DeletesUsersAndLogsEvents(
SutProvider<DeleteManagedOrganizationUserAccountCommand> sutProvider, User user1, User user2, Guid organizationId,
[OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.User)] OrganizationUser orgUser1,
[OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.User)] OrganizationUser orgUser2)
{
// Arrange
orgUser1.OrganizationId = orgUser2.OrganizationId = organizationId;
orgUser1.UserId = user1.Id;
orgUser2.UserId = user2.Id;
sutProvider.GetDependency<IOrganizationUserRepository>()
.GetManyAsync(Arg.Any<IEnumerable<Guid>>())
.Returns(new List<OrganizationUser> { orgUser1, orgUser2 });
sutProvider.GetDependency<IUserRepository>()
.GetManyAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user1.Id) && ids.Contains(user2.Id)))
.Returns(new[] { user1, user2 });
sutProvider.GetDependency<IGetOrganizationUsersManagementStatusQuery>()
.GetUsersOrganizationManagementStatusAsync(organizationId, Arg.Any<IEnumerable<Guid>>())
.Returns(new Dictionary<Guid, bool> { { orgUser1.Id, true }, { orgUser2.Id, true } });
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(false);
// Act
var userIds = new[] { orgUser1.Id, orgUser2.Id };
var results = await sutProvider.Sut.DeleteManyUsersAsync(organizationId, userIds, null);
// Assert
Assert.Equal(2, results.Count());
Assert.All(results, r => Assert.Empty(r.Item2));
await sutProvider.GetDependency<IOrganizationUserRepository>().Received(1).GetManyAsync(userIds);
await sutProvider.GetDependency<IUserService>().Received(0).DeleteManyAsync(Arg.Any<IEnumerable<User>>());
await sutProvider.GetDependency<IUserService>().Received(2).DeleteAsync(Arg.Any<User>());
await sutProvider.GetDependency<IEventService>().Received(1).LogOrganizationUserEventsAsync(
Arg.Is<IEnumerable<(OrganizationUser, EventType, DateTime?)>>(events =>
events.Count(e => e.Item1.Id == orgUser1.Id && e.Item2 == EventType.OrganizationUser_Deleted) == 1
&& events.Count(e => e.Item1.Id == orgUser2.Id && e.Item2 == EventType.OrganizationUser_Deleted) == 1));
}
[Theory]
[BitAutoData]
public async Task DeleteManyUsersAsync_WhenFeatureFlagEnabled_WhenUserNotFound_ReturnsErrorMessage(
SutProvider<DeleteManagedOrganizationUserAccountCommand> sutProvider,
Guid organizationId,
Guid orgUserId)
{
// Arrang
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true);
// Act
var result = await sutProvider.Sut.DeleteManyUsersAsync(organizationId, new[] { orgUserId }, null);
@ -287,6 +339,30 @@ public class DeleteManagedOrganizationUserAccountCommandTests
Assert.Single(result);
Assert.Equal(orgUserId, result.First().Item1);
Assert.Contains("Member not found.", result.First().Item2);
await sutProvider.GetDependency<IUserService>().Received(1).DeleteManyAsync(Arg.Any<IEnumerable<User>>());
await sutProvider.GetDependency<IEventService>().Received(0)
.LogOrganizationUserEventsAsync(Arg.Any<IEnumerable<(OrganizationUser, EventType, DateTime?)>>());
}
[Theory]
[BitAutoData]
public async Task DeleteManyUsersAsync_WhenFeatureFlagDisabled_WhenUserNotFound_ReturnsErrorMessage(
SutProvider<DeleteManagedOrganizationUserAccountCommand> sutProvider,
Guid organizationId,
Guid orgUserId)
{
// Arrang
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(false);
// Act
var result = await sutProvider.Sut.DeleteManyUsersAsync(organizationId, new[] { orgUserId }, null);
// Assert
Assert.Single(result);
Assert.Equal(orgUserId, result.First().Item1);
Assert.Contains("Member not found.", result.First().Item2);
await sutProvider.GetDependency<IUserService>().Received(0).DeleteManyAsync(Arg.Any<IEnumerable<User>>());
await sutProvider.GetDependency<IUserService>().Received(0).DeleteAsync(Arg.Any<User>());
await sutProvider.GetDependency<IEventService>().Received(0)
.LogOrganizationUserEventsAsync(Arg.Any<IEnumerable<(OrganizationUser, EventType, DateTime?)>>());