diff --git a/src/Api/AdminConsole/Controllers/OrganizationAuthRequestsController.cs b/src/Api/AdminConsole/Controllers/OrganizationAuthRequestsController.cs index cb06b6211117..dbb73f870699 100644 --- a/src/Api/AdminConsole/Controllers/OrganizationAuthRequestsController.cs +++ b/src/Api/AdminConsole/Controllers/OrganizationAuthRequestsController.cs @@ -1,12 +1,14 @@ using Bit.Api.AdminConsole.Models.Request; using Bit.Api.AdminConsole.Models.Response; using Bit.Api.Models.Response; +using Bit.Core; using Bit.Core.AdminConsole.OrganizationAuth.Interfaces; using Bit.Core.Auth.Models.Api.Request.AuthRequest; using Bit.Core.Auth.Services; using Bit.Core.Context; using Bit.Core.Exceptions; using Bit.Core.Repositories; +using Bit.Core.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -73,7 +75,15 @@ public async Task BulkDenyRequests(Guid orgId, [FromBody] BulkDenyAdminAuthReque } } - private async Task ValidateAdminRequest(Guid orgId) + [RequireFeature(FeatureFlagKeys.BulkDeviceApproval)] + [HttpPost("")] + public async Task UpdateManyAuthRequests(Guid orgId, [FromBody] IEnumerable model) + { + await ValidateAdminRequest(orgId); + await _updateOrganizationAuthRequestCommand.UpdateAsync(orgId, model.Select(x => x.ToOrganizationAuthRequestUpdate())); + } + + public async Task ValidateAdminRequest(Guid orgId) { if (!await _currentContext.ManageResetPassword(orgId)) { diff --git a/src/Api/AdminConsole/Models/Request/OrganizationAuthRequestUpdateManyRequestModel.cs b/src/Api/AdminConsole/Models/Request/OrganizationAuthRequestUpdateManyRequestModel.cs new file mode 100644 index 000000000000..34a45369b2c8 --- /dev/null +++ b/src/Api/AdminConsole/Models/Request/OrganizationAuthRequestUpdateManyRequestModel.cs @@ -0,0 +1,24 @@ +using Bit.Core.AdminConsole.OrganizationAuth.Models; +using Bit.Core.Utilities; + +namespace Bit.Api.AdminConsole.Models.Request; + +public class OrganizationAuthRequestUpdateManyRequestModel +{ + public Guid Id { get; set; } + + [EncryptedString] + public string Key { get; set; } + + public bool Approved { get; set; } + + public OrganizationAuthRequestUpdate ToOrganizationAuthRequestUpdate() + { + return new OrganizationAuthRequestUpdate + { + Id = Id, + Key = Key, + Approved = Approved + }; + } +} diff --git a/test/Api.Test/AdminConsole/Controllers/OrganizationAuthRequestsControllerTests.cs b/test/Api.Test/AdminConsole/Controllers/OrganizationAuthRequestsControllerTests.cs new file mode 100644 index 000000000000..0008f6fe6fcf --- /dev/null +++ b/test/Api.Test/AdminConsole/Controllers/OrganizationAuthRequestsControllerTests.cs @@ -0,0 +1,64 @@ +using Bit.Api.AdminConsole.Controllers; +using Bit.Api.AdminConsole.Models.Request; +using Bit.Core.Context; +using Bit.Test.Common.AutoFixture; +using Bit.Test.Common.AutoFixture.Attributes; +using NSubstitute; +using Xunit; + +namespace Bit.Api.Test.AdminConsole.Controllers; + +[ControllerCustomize(typeof(OrganizationAuthRequestsController))] +[SutProviderCustomize] +public class OrganizationAuthRequestsControllerTests +{ + + [Theory] + [BitAutoData] + public async Task ValidateAdminRequest_UserDoesNotHaveManageResetPasswordPermissions_ThrowsUnauthorized( + SutProvider sutProvider, + Guid organizationId + ) + { + sutProvider.GetDependency().ManageResetPassword(organizationId).Returns(false); + + await Assert.ThrowsAsync(() => + sutProvider.Sut.ValidateAdminRequest(organizationId)); + } + + [Theory] + [BitAutoData] + public async Task ValidateAdminRequest_UserHasManageResetPasswordPermissions_DoesNotThrow( + SutProvider sutProvider, + Guid organizationId + ) + { + sutProvider.GetDependency().ManageResetPassword(organizationId).Returns(true); + await sutProvider.Sut.ValidateAdminRequest(organizationId); + } + + [Theory] + [BitAutoData] + public async Task UpdateManyAuthRequests_ValidInput_DoesNotThrow( + SutProvider sutProvider, + IEnumerable request, + Guid organizationId + ) + { + sutProvider.GetDependency().ManageResetPassword(organizationId).Returns(true); + await sutProvider.Sut.UpdateManyAuthRequests(organizationId, request); + } + + [Theory] + [BitAutoData] + public async Task UpdateManyAuthRequests_NotPermissioned_ThrowsUnauthorized( + SutProvider sutProvider, + IEnumerable request, + Guid organizationId + ) + { + sutProvider.GetDependency().ManageResetPassword(organizationId).Returns(false); + await Assert.ThrowsAsync(() => + sutProvider.Sut.UpdateManyAuthRequests(organizationId, request)); + } +}