mirror of
https://github.com/bitwarden/server.git
synced 2024-11-24 12:35:25 +01:00
[PM-10323] Remove user verification from organization user deletion methods (#4965)
This commit is contained in:
parent
96862b974f
commit
60672bbe48
@ -1,6 +1,5 @@
|
|||||||
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||||
using Bit.Api.AdminConsole.Models.Response.Organizations;
|
using Bit.Api.AdminConsole.Models.Response.Organizations;
|
||||||
using Bit.Api.Auth.Models.Request.Accounts;
|
|
||||||
using Bit.Api.Models.Request.Organizations;
|
using Bit.Api.Models.Request.Organizations;
|
||||||
using Bit.Api.Models.Response;
|
using Bit.Api.Models.Response;
|
||||||
using Bit.Api.Vault.AuthorizationHandlers.Collections;
|
using Bit.Api.Vault.AuthorizationHandlers.Collections;
|
||||||
@ -545,7 +544,7 @@ public class OrganizationUsersController : Controller
|
|||||||
[RequireFeature(FeatureFlagKeys.AccountDeprovisioning)]
|
[RequireFeature(FeatureFlagKeys.AccountDeprovisioning)]
|
||||||
[HttpDelete("{id}/delete-account")]
|
[HttpDelete("{id}/delete-account")]
|
||||||
[HttpPost("{id}/delete-account")]
|
[HttpPost("{id}/delete-account")]
|
||||||
public async Task DeleteAccount(Guid orgId, Guid id, [FromBody] SecretVerificationRequestModel model)
|
public async Task DeleteAccount(Guid orgId, Guid id)
|
||||||
{
|
{
|
||||||
if (!await _currentContext.ManageUsers(orgId))
|
if (!await _currentContext.ManageUsers(orgId))
|
||||||
{
|
{
|
||||||
@ -558,19 +557,13 @@ public class OrganizationUsersController : Controller
|
|||||||
throw new UnauthorizedAccessException();
|
throw new UnauthorizedAccessException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!await _userService.VerifySecretAsync(currentUser, model.Secret))
|
|
||||||
{
|
|
||||||
await Task.Delay(2000);
|
|
||||||
throw new BadRequestException(string.Empty, "User verification failed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
await _deleteManagedOrganizationUserAccountCommand.DeleteUserAsync(orgId, id, currentUser.Id);
|
await _deleteManagedOrganizationUserAccountCommand.DeleteUserAsync(orgId, id, currentUser.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
[RequireFeature(FeatureFlagKeys.AccountDeprovisioning)]
|
[RequireFeature(FeatureFlagKeys.AccountDeprovisioning)]
|
||||||
[HttpDelete("delete-account")]
|
[HttpDelete("delete-account")]
|
||||||
[HttpPost("delete-account")]
|
[HttpPost("delete-account")]
|
||||||
public async Task<ListResponseModel<OrganizationUserBulkResponseModel>> BulkDeleteAccount(Guid orgId, [FromBody] SecureOrganizationUserBulkRequestModel model)
|
public async Task<ListResponseModel<OrganizationUserBulkResponseModel>> BulkDeleteAccount(Guid orgId, [FromBody] OrganizationUserBulkRequestModel model)
|
||||||
{
|
{
|
||||||
if (!await _currentContext.ManageUsers(orgId))
|
if (!await _currentContext.ManageUsers(orgId))
|
||||||
{
|
{
|
||||||
@ -583,12 +576,6 @@ public class OrganizationUsersController : Controller
|
|||||||
throw new UnauthorizedAccessException();
|
throw new UnauthorizedAccessException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!await _userService.VerifySecretAsync(currentUser, model.Secret))
|
|
||||||
{
|
|
||||||
await Task.Delay(2000);
|
|
||||||
throw new BadRequestException(string.Empty, "User verification failed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var results = await _deleteManagedOrganizationUserAccountCommand.DeleteManyUsersAsync(orgId, model.Ids, currentUser.Id);
|
var results = await _deleteManagedOrganizationUserAccountCommand.DeleteManyUsersAsync(orgId, model.Ids, currentUser.Id);
|
||||||
|
|
||||||
return new ListResponseModel<OrganizationUserBulkResponseModel>(results.Select(r =>
|
return new ListResponseModel<OrganizationUserBulkResponseModel>(results.Select(r =>
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using Bit.Api.Auth.Models.Request.Accounts;
|
|
||||||
|
|
||||||
namespace Bit.Api.AdminConsole.Models.Request.Organizations;
|
|
||||||
|
|
||||||
public class SecureOrganizationUserBulkRequestModel : SecretVerificationRequestModel
|
|
||||||
{
|
|
||||||
[Required]
|
|
||||||
public IEnumerable<Guid> Ids { get; set; }
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using Bit.Api.AdminConsole.Controllers;
|
using Bit.Api.AdminConsole.Controllers;
|
||||||
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||||
using Bit.Api.Auth.Models.Request.Accounts;
|
|
||||||
using Bit.Api.Vault.AuthorizationHandlers.Collections;
|
using Bit.Api.Vault.AuthorizationHandlers.Collections;
|
||||||
using Bit.Core;
|
using Bit.Core;
|
||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
@ -273,17 +272,12 @@ public class OrganizationUsersControllerTests
|
|||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData]
|
[BitAutoData]
|
||||||
public async Task DeleteAccount_WhenUserCanManageUsers_Success(
|
public async Task DeleteAccount_WhenUserCanManageUsers_Success(
|
||||||
Guid orgId,
|
Guid orgId, Guid id, User currentUser, SutProvider<OrganizationUsersController> sutProvider)
|
||||||
Guid id,
|
|
||||||
SecretVerificationRequestModel model,
|
|
||||||
User currentUser,
|
|
||||||
SutProvider<OrganizationUsersController> sutProvider)
|
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(true);
|
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(true);
|
||||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(currentUser);
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(currentUser);
|
||||||
sutProvider.GetDependency<IUserService>().VerifySecretAsync(currentUser, model.Secret).Returns(true);
|
|
||||||
|
|
||||||
await sutProvider.Sut.DeleteAccount(orgId, id, model);
|
await sutProvider.Sut.DeleteAccount(orgId, id);
|
||||||
|
|
||||||
await sutProvider.GetDependency<IDeleteManagedOrganizationUserAccountCommand>()
|
await sutProvider.GetDependency<IDeleteManagedOrganizationUserAccountCommand>()
|
||||||
.Received(1)
|
.Received(1)
|
||||||
@ -293,60 +287,34 @@ public class OrganizationUsersControllerTests
|
|||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData]
|
[BitAutoData]
|
||||||
public async Task DeleteAccount_WhenUserCannotManageUsers_ThrowsNotFoundException(
|
public async Task DeleteAccount_WhenUserCannotManageUsers_ThrowsNotFoundException(
|
||||||
Guid orgId,
|
Guid orgId, Guid id, SutProvider<OrganizationUsersController> sutProvider)
|
||||||
Guid id,
|
|
||||||
SecretVerificationRequestModel model,
|
|
||||||
SutProvider<OrganizationUsersController> sutProvider)
|
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(false);
|
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(false);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<NotFoundException>(() =>
|
await Assert.ThrowsAsync<NotFoundException>(() =>
|
||||||
sutProvider.Sut.DeleteAccount(orgId, id, model));
|
sutProvider.Sut.DeleteAccount(orgId, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData]
|
[BitAutoData]
|
||||||
public async Task DeleteAccount_WhenCurrentUserNotFound_ThrowsUnauthorizedAccessException(
|
public async Task DeleteAccount_WhenCurrentUserNotFound_ThrowsUnauthorizedAccessException(
|
||||||
Guid orgId,
|
Guid orgId, Guid id, SutProvider<OrganizationUsersController> sutProvider)
|
||||||
Guid id,
|
|
||||||
SecretVerificationRequestModel model,
|
|
||||||
SutProvider<OrganizationUsersController> sutProvider)
|
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(true);
|
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(true);
|
||||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs((User)null);
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs((User)null);
|
||||||
|
|
||||||
await Assert.ThrowsAsync<UnauthorizedAccessException>(() =>
|
await Assert.ThrowsAsync<UnauthorizedAccessException>(() =>
|
||||||
sutProvider.Sut.DeleteAccount(orgId, id, model));
|
sutProvider.Sut.DeleteAccount(orgId, id));
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[BitAutoData]
|
|
||||||
public async Task DeleteAccount_WhenSecretVerificationFails_ThrowsBadRequestException(
|
|
||||||
Guid orgId,
|
|
||||||
Guid id,
|
|
||||||
SecretVerificationRequestModel model,
|
|
||||||
User currentUser,
|
|
||||||
SutProvider<OrganizationUsersController> sutProvider)
|
|
||||||
{
|
|
||||||
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(true);
|
|
||||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(currentUser);
|
|
||||||
sutProvider.GetDependency<IUserService>().VerifySecretAsync(currentUser, model.Secret).Returns(false);
|
|
||||||
|
|
||||||
await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.DeleteAccount(orgId, id, model));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData]
|
[BitAutoData]
|
||||||
public async Task BulkDeleteAccount_WhenUserCanManageUsers_Success(
|
public async Task BulkDeleteAccount_WhenUserCanManageUsers_Success(
|
||||||
Guid orgId,
|
Guid orgId, OrganizationUserBulkRequestModel model, User currentUser,
|
||||||
SecureOrganizationUserBulkRequestModel model,
|
List<(Guid, string)> deleteResults, SutProvider<OrganizationUsersController> sutProvider)
|
||||||
User currentUser,
|
|
||||||
List<(Guid, string)> deleteResults,
|
|
||||||
SutProvider<OrganizationUsersController> sutProvider)
|
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(true);
|
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(true);
|
||||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(currentUser);
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(currentUser);
|
||||||
sutProvider.GetDependency<IUserService>().VerifySecretAsync(currentUser, model.Secret).Returns(true);
|
|
||||||
sutProvider.GetDependency<IDeleteManagedOrganizationUserAccountCommand>()
|
sutProvider.GetDependency<IDeleteManagedOrganizationUserAccountCommand>()
|
||||||
.DeleteManyUsersAsync(orgId, model.Ids, currentUser.Id)
|
.DeleteManyUsersAsync(orgId, model.Ids, currentUser.Id)
|
||||||
.Returns(deleteResults);
|
.Returns(deleteResults);
|
||||||
@ -363,9 +331,7 @@ public class OrganizationUsersControllerTests
|
|||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData]
|
[BitAutoData]
|
||||||
public async Task BulkDeleteAccount_WhenUserCannotManageUsers_ThrowsNotFoundException(
|
public async Task BulkDeleteAccount_WhenUserCannotManageUsers_ThrowsNotFoundException(
|
||||||
Guid orgId,
|
Guid orgId, OrganizationUserBulkRequestModel model, SutProvider<OrganizationUsersController> sutProvider)
|
||||||
SecureOrganizationUserBulkRequestModel model,
|
|
||||||
SutProvider<OrganizationUsersController> sutProvider)
|
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(false);
|
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(false);
|
||||||
|
|
||||||
@ -376,9 +342,7 @@ public class OrganizationUsersControllerTests
|
|||||||
[Theory]
|
[Theory]
|
||||||
[BitAutoData]
|
[BitAutoData]
|
||||||
public async Task BulkDeleteAccount_WhenCurrentUserNotFound_ThrowsUnauthorizedAccessException(
|
public async Task BulkDeleteAccount_WhenCurrentUserNotFound_ThrowsUnauthorizedAccessException(
|
||||||
Guid orgId,
|
Guid orgId, OrganizationUserBulkRequestModel model, SutProvider<OrganizationUsersController> sutProvider)
|
||||||
SecureOrganizationUserBulkRequestModel model,
|
|
||||||
SutProvider<OrganizationUsersController> sutProvider)
|
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(true);
|
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(true);
|
||||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs((User)null);
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs((User)null);
|
||||||
@ -387,21 +351,6 @@ public class OrganizationUsersControllerTests
|
|||||||
sutProvider.Sut.BulkDeleteAccount(orgId, model));
|
sutProvider.Sut.BulkDeleteAccount(orgId, model));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[BitAutoData]
|
|
||||||
public async Task BulkDeleteAccount_WhenSecretVerificationFails_ThrowsBadRequestException(
|
|
||||||
Guid orgId,
|
|
||||||
SecureOrganizationUserBulkRequestModel model,
|
|
||||||
User currentUser,
|
|
||||||
SutProvider<OrganizationUsersController> sutProvider)
|
|
||||||
{
|
|
||||||
sutProvider.GetDependency<ICurrentContext>().ManageUsers(orgId).Returns(true);
|
|
||||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(currentUser);
|
|
||||||
sutProvider.GetDependency<IUserService>().VerifySecretAsync(currentUser, model.Secret).Returns(false);
|
|
||||||
|
|
||||||
await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.BulkDeleteAccount(orgId, model));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GetMany_Setup(OrganizationAbility organizationAbility,
|
private void GetMany_Setup(OrganizationAbility organizationAbility,
|
||||||
ICollection<OrganizationUserUserDetails> organizationUsers,
|
ICollection<OrganizationUserUserDetails> organizationUsers,
|
||||||
SutProvider<OrganizationUsersController> sutProvider)
|
SutProvider<OrganizationUsersController> sutProvider)
|
||||||
|
Loading…
Reference in New Issue
Block a user