mirror of
https://github.com/bitwarden/server.git
synced 2025-07-06 10:32:49 -05:00
[AC-607] Extract IOrganizationService.DeleteUserAsync into IRemoveOrganizationUserCommand (#4803)
* Add HasConfirmedOwnersExceptQuery class, interface and unit tests * Register IHasConfirmedOwnersExceptQuery for dependency injection * Replace OrganizationService.HasConfirmedOwnersExceptAsync with HasConfirmedOwnersExceptQuery * Refactor DeleteManagedOrganizationUserAccountCommand to use IHasConfirmedOwnersExceptQuery * Fix unit tests * Extract IOrganizationService.RemoveUserAsync into IRemoveOrganizationUserCommand; Update unit tests * Extract IOrganizationService.RemoveUsersAsync into IRemoveOrganizationUserCommand; Update unit tests * Refactor RemoveUserAsync(Guid organizationId, Guid userId) to use ValidateDeleteUser * Refactor RemoveOrganizationUserCommandTests to use more descriptive method names * Refactor controller actions to accept Guid directly instead of parsing strings * Add unit tests for removing OrganizationUser by UserId * Refactor remove OrganizationUser by UserId method * Add summary to IHasConfirmedOwnersExceptQuery
This commit is contained in:
@ -51,6 +51,7 @@ public class OrganizationUsersController : Controller
|
||||
private readonly ISsoConfigRepository _ssoConfigRepository;
|
||||
private readonly IOrganizationUserUserDetailsQuery _organizationUserUserDetailsQuery;
|
||||
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
|
||||
private readonly IRemoveOrganizationUserCommand _removeOrganizationUserCommand;
|
||||
private readonly IDeleteManagedOrganizationUserAccountCommand _deleteManagedOrganizationUserAccountCommand;
|
||||
|
||||
public OrganizationUsersController(
|
||||
@ -71,6 +72,7 @@ public class OrganizationUsersController : Controller
|
||||
ISsoConfigRepository ssoConfigRepository,
|
||||
IOrganizationUserUserDetailsQuery organizationUserUserDetailsQuery,
|
||||
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
|
||||
IRemoveOrganizationUserCommand removeOrganizationUserCommand,
|
||||
IDeleteManagedOrganizationUserAccountCommand deleteManagedOrganizationUserAccountCommand)
|
||||
{
|
||||
_organizationRepository = organizationRepository;
|
||||
@ -90,6 +92,7 @@ public class OrganizationUsersController : Controller
|
||||
_ssoConfigRepository = ssoConfigRepository;
|
||||
_organizationUserUserDetailsQuery = organizationUserUserDetailsQuery;
|
||||
_twoFactorIsEnabledQuery = twoFactorIsEnabledQuery;
|
||||
_removeOrganizationUserCommand = removeOrganizationUserCommand;
|
||||
_deleteManagedOrganizationUserAccountCommand = deleteManagedOrganizationUserAccountCommand;
|
||||
}
|
||||
|
||||
@ -502,30 +505,28 @@ public class OrganizationUsersController : Controller
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[HttpPost("{id}/remove")]
|
||||
public async Task Remove(string orgId, string id)
|
||||
public async Task Remove(Guid orgId, Guid id)
|
||||
{
|
||||
var orgGuidId = new Guid(orgId);
|
||||
if (!await _currentContext.ManageUsers(orgGuidId))
|
||||
if (!await _currentContext.ManageUsers(orgId))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var userId = _userService.GetProperUserId(User);
|
||||
await _organizationService.RemoveUserAsync(orgGuidId, new Guid(id), userId.Value);
|
||||
await _removeOrganizationUserCommand.RemoveUserAsync(orgId, id, userId.Value);
|
||||
}
|
||||
|
||||
[HttpDelete("")]
|
||||
[HttpPost("remove")]
|
||||
public async Task<ListResponseModel<OrganizationUserBulkResponseModel>> BulkRemove(string orgId, [FromBody] OrganizationUserBulkRequestModel model)
|
||||
public async Task<ListResponseModel<OrganizationUserBulkResponseModel>> BulkRemove(Guid orgId, [FromBody] OrganizationUserBulkRequestModel model)
|
||||
{
|
||||
var orgGuidId = new Guid(orgId);
|
||||
if (!await _currentContext.ManageUsers(orgGuidId))
|
||||
if (!await _currentContext.ManageUsers(orgId))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var userId = _userService.GetProperUserId(User);
|
||||
var result = await _organizationService.RemoveUsersAsync(orgGuidId, model.Ids, userId.Value);
|
||||
var result = await _removeOrganizationUserCommand.RemoveUsersAsync(orgId, model.Ids, userId.Value);
|
||||
return new ListResponseModel<OrganizationUserBulkResponseModel>(result.Select(r =>
|
||||
new OrganizationUserBulkResponseModel(r.Item1.Id, r.Item2)));
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ using Bit.Core.AdminConsole.Enums;
|
||||
using Bit.Core.AdminConsole.Models.Business.Tokenables;
|
||||
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationApiKeys.Interfaces;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.Auth.Enums;
|
||||
using Bit.Core.Auth.Repositories;
|
||||
@ -55,6 +56,7 @@ public class OrganizationsController : Controller
|
||||
private readonly IProviderRepository _providerRepository;
|
||||
private readonly IProviderBillingService _providerBillingService;
|
||||
private readonly IDataProtectorTokenFactory<OrgDeleteTokenable> _orgDeleteTokenDataFactory;
|
||||
private readonly IRemoveOrganizationUserCommand _removeOrganizationUserCommand;
|
||||
|
||||
public OrganizationsController(
|
||||
IOrganizationRepository organizationRepository,
|
||||
@ -74,7 +76,8 @@ public class OrganizationsController : Controller
|
||||
IPushNotificationService pushNotificationService,
|
||||
IProviderRepository providerRepository,
|
||||
IProviderBillingService providerBillingService,
|
||||
IDataProtectorTokenFactory<OrgDeleteTokenable> orgDeleteTokenDataFactory)
|
||||
IDataProtectorTokenFactory<OrgDeleteTokenable> orgDeleteTokenDataFactory,
|
||||
IRemoveOrganizationUserCommand removeOrganizationUserCommand)
|
||||
{
|
||||
_organizationRepository = organizationRepository;
|
||||
_organizationUserRepository = organizationUserRepository;
|
||||
@ -94,6 +97,7 @@ public class OrganizationsController : Controller
|
||||
_providerRepository = providerRepository;
|
||||
_providerBillingService = providerBillingService;
|
||||
_orgDeleteTokenDataFactory = orgDeleteTokenDataFactory;
|
||||
_removeOrganizationUserCommand = removeOrganizationUserCommand;
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
@ -229,24 +233,22 @@ public class OrganizationsController : Controller
|
||||
}
|
||||
|
||||
[HttpPost("{id}/leave")]
|
||||
public async Task Leave(string id)
|
||||
public async Task Leave(Guid id)
|
||||
{
|
||||
var orgGuidId = new Guid(id);
|
||||
if (!await _currentContext.OrganizationUser(orgGuidId))
|
||||
if (!await _currentContext.OrganizationUser(id))
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var user = await _userService.GetUserByPrincipalAsync(User);
|
||||
|
||||
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(orgGuidId);
|
||||
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(id);
|
||||
if (ssoConfig?.GetData()?.MemberDecryptionType == MemberDecryptionType.KeyConnector && user.UsesKeyConnector)
|
||||
{
|
||||
throw new BadRequestException("Your organization's Single Sign-On settings prevent you from leaving.");
|
||||
}
|
||||
|
||||
|
||||
await _organizationService.RemoveUserAsync(orgGuidId, user.Id);
|
||||
await _removeOrganizationUserCommand.RemoveUserAsync(id, user.Id);
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
|
Reference in New Issue
Block a user