mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 23:52:50 -05:00
Merge branch 'main' into auth/pm-20348/extension-auth-approvals-add-auth-request-endpoint
This commit is contained in:
@ -3,7 +3,7 @@ using Bit.Api.AdminConsole.Controllers;
|
||||
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||
using Bit.Api.AdminConsole.Models.Response.Organizations;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Data.Integrations;
|
||||
using Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
|
@ -30,6 +30,7 @@ public class OrganizationUserControllerPutTests
|
||||
OrganizationUser organizationUser, OrganizationAbility organizationAbility,
|
||||
SutProvider<OrganizationUsersController> sutProvider, Guid savingUserId)
|
||||
{
|
||||
// Arrange
|
||||
Put_Setup(sutProvider, organizationAbility, organizationUser, savingUserId, currentCollectionAccess: []);
|
||||
|
||||
// Authorize all changes for basic happy path test
|
||||
@ -41,15 +42,18 @@ public class OrganizationUserControllerPutTests
|
||||
// Save these for later - organizationUser object will be mutated
|
||||
var orgUserId = organizationUser.Id;
|
||||
var orgUserEmail = organizationUser.Email;
|
||||
var existingUserType = organizationUser.Type;
|
||||
|
||||
// Act
|
||||
await sutProvider.Sut.Put(organizationAbility.Id, organizationUser.Id, model);
|
||||
|
||||
// Assert
|
||||
await sutProvider.GetDependency<IUpdateOrganizationUserCommand>().Received(1).UpdateUserAsync(Arg.Is<OrganizationUser>(ou =>
|
||||
ou.Type == model.Type &&
|
||||
ou.Permissions == CoreHelpers.ClassToJsonData(model.Permissions) &&
|
||||
ou.AccessSecretsManager == model.AccessSecretsManager &&
|
||||
ou.Id == orgUserId &&
|
||||
ou.Email == orgUserEmail),
|
||||
ou.Email == orgUserEmail), existingUserType,
|
||||
savingUserId,
|
||||
Arg.Is<List<CollectionAccessSelection>>(cas =>
|
||||
cas.All(c => model.Collections.Any(m => m.Id == c.Id))),
|
||||
@ -77,6 +81,7 @@ public class OrganizationUserControllerPutTests
|
||||
OrganizationUser organizationUser, OrganizationAbility organizationAbility,
|
||||
SutProvider<OrganizationUsersController> sutProvider, Guid savingUserId)
|
||||
{
|
||||
// Arrange
|
||||
// Updating self
|
||||
organizationUser.UserId = savingUserId;
|
||||
organizationAbility.AllowAdminAccessToAllCollectionItems = false;
|
||||
@ -88,15 +93,18 @@ public class OrganizationUserControllerPutTests
|
||||
|
||||
var orgUserId = organizationUser.Id;
|
||||
var orgUserEmail = organizationUser.Email;
|
||||
var existingUserType = organizationUser.Type;
|
||||
|
||||
// Act
|
||||
await sutProvider.Sut.Put(organizationAbility.Id, organizationUser.Id, model);
|
||||
|
||||
// Assert
|
||||
await sutProvider.GetDependency<IUpdateOrganizationUserCommand>().Received(1).UpdateUserAsync(Arg.Is<OrganizationUser>(ou =>
|
||||
ou.Type == model.Type &&
|
||||
ou.Permissions == CoreHelpers.ClassToJsonData(model.Permissions) &&
|
||||
ou.AccessSecretsManager == model.AccessSecretsManager &&
|
||||
ou.Id == orgUserId &&
|
||||
ou.Email == orgUserEmail),
|
||||
ou.Type == model.Type &&
|
||||
ou.Permissions == CoreHelpers.ClassToJsonData(model.Permissions) &&
|
||||
ou.AccessSecretsManager == model.AccessSecretsManager &&
|
||||
ou.Id == orgUserId &&
|
||||
ou.Email == orgUserEmail), existingUserType,
|
||||
savingUserId,
|
||||
Arg.Is<List<CollectionAccessSelection>>(cas =>
|
||||
cas.All(c => model.Collections.Any(m => m.Id == c.Id))),
|
||||
@ -110,6 +118,7 @@ public class OrganizationUserControllerPutTests
|
||||
OrganizationUser organizationUser, OrganizationAbility organizationAbility,
|
||||
SutProvider<OrganizationUsersController> sutProvider, Guid savingUserId)
|
||||
{
|
||||
// Arrange
|
||||
// Updating self
|
||||
organizationUser.UserId = savingUserId;
|
||||
organizationAbility.AllowAdminAccessToAllCollectionItems = true;
|
||||
@ -121,15 +130,18 @@ public class OrganizationUserControllerPutTests
|
||||
|
||||
var orgUserId = organizationUser.Id;
|
||||
var orgUserEmail = organizationUser.Email;
|
||||
var existingUserType = organizationUser.Type;
|
||||
|
||||
// Act
|
||||
await sutProvider.Sut.Put(organizationAbility.Id, organizationUser.Id, model);
|
||||
|
||||
// Assert
|
||||
await sutProvider.GetDependency<IUpdateOrganizationUserCommand>().Received(1).UpdateUserAsync(Arg.Is<OrganizationUser>(ou =>
|
||||
ou.Type == model.Type &&
|
||||
ou.Permissions == CoreHelpers.ClassToJsonData(model.Permissions) &&
|
||||
ou.AccessSecretsManager == model.AccessSecretsManager &&
|
||||
ou.Id == orgUserId &&
|
||||
ou.Email == orgUserEmail),
|
||||
ou.Type == model.Type &&
|
||||
ou.Permissions == CoreHelpers.ClassToJsonData(model.Permissions) &&
|
||||
ou.AccessSecretsManager == model.AccessSecretsManager &&
|
||||
ou.Id == orgUserId &&
|
||||
ou.Email == orgUserEmail), existingUserType,
|
||||
savingUserId,
|
||||
Arg.Is<List<CollectionAccessSelection>>(cas =>
|
||||
cas.All(c => model.Collections.Any(m => m.Id == c.Id))),
|
||||
@ -142,6 +154,7 @@ public class OrganizationUserControllerPutTests
|
||||
OrganizationUser organizationUser, OrganizationAbility organizationAbility,
|
||||
SutProvider<OrganizationUsersController> sutProvider, Guid savingUserId)
|
||||
{
|
||||
// Arrange
|
||||
var editedCollectionId = CoreHelpers.GenerateComb();
|
||||
var readonlyCollectionId1 = CoreHelpers.GenerateComb();
|
||||
var readonlyCollectionId2 = CoreHelpers.GenerateComb();
|
||||
@ -194,16 +207,19 @@ public class OrganizationUserControllerPutTests
|
||||
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), Arg.Is<Collection>(c => c.Id == readonlyCollectionId1 || c.Id == readonlyCollectionId2),
|
||||
Arg.Is<IEnumerable<IAuthorizationRequirement>>(reqs => reqs.Contains(BulkCollectionOperations.ModifyUserAccess)))
|
||||
.Returns(AuthorizationResult.Failed());
|
||||
var existingUserType = organizationUser.Type;
|
||||
|
||||
// Act
|
||||
await sutProvider.Sut.Put(organizationAbility.Id, organizationUser.Id, model);
|
||||
|
||||
// Assert
|
||||
// Expect all collection access (modified and unmodified) to be saved
|
||||
await sutProvider.GetDependency<IUpdateOrganizationUserCommand>().Received(1).UpdateUserAsync(Arg.Is<OrganizationUser>(ou =>
|
||||
ou.Type == model.Type &&
|
||||
ou.Permissions == CoreHelpers.ClassToJsonData(model.Permissions) &&
|
||||
ou.AccessSecretsManager == model.AccessSecretsManager &&
|
||||
ou.Id == orgUserId &&
|
||||
ou.Email == orgUserEmail),
|
||||
ou.Type == model.Type &&
|
||||
ou.Permissions == CoreHelpers.ClassToJsonData(model.Permissions) &&
|
||||
ou.AccessSecretsManager == model.AccessSecretsManager &&
|
||||
ou.Id == orgUserId &&
|
||||
ou.Email == orgUserEmail), existingUserType,
|
||||
savingUserId,
|
||||
Arg.Is<List<CollectionAccessSelection>>(cas =>
|
||||
cas.Select(c => c.Id).SequenceEqual(currentCollectionAccess.Select(c => c.Id)) &&
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
||||
using Bit.Core.AdminConsole.Models.Data.Integrations;
|
||||
using Bit.Core.AdminConsole.Models.Data.EventIntegrations;
|
||||
using Bit.Core.Enums;
|
||||
using Xunit;
|
||||
|
||||
|
@ -18,210 +18,6 @@ namespace Bit.Api.Test.Platform.Push.Controllers;
|
||||
[SutProviderCustomize]
|
||||
public class PushControllerTests
|
||||
{
|
||||
[Theory]
|
||||
[BitAutoData(false, true)]
|
||||
[BitAutoData(false, false)]
|
||||
[BitAutoData(true, true)]
|
||||
public async Task SendAsync_InstallationIdNotSetOrSelfHosted_BadRequest(bool haveInstallationId, bool selfHosted,
|
||||
SutProvider<PushController> sutProvider, Guid installationId, Guid userId, Guid organizationId)
|
||||
{
|
||||
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = selfHosted;
|
||||
if (haveInstallationId)
|
||||
{
|
||||
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId);
|
||||
}
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SendAsync(new PushSendRequestModel
|
||||
{
|
||||
Type = PushType.Notification,
|
||||
UserId = userId.ToString(),
|
||||
OrganizationId = organizationId.ToString(),
|
||||
InstallationId = installationId.ToString(),
|
||||
Payload = "test-payload"
|
||||
}));
|
||||
|
||||
Assert.Equal("Not correctly configured for push relays.", exception.Message);
|
||||
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToUserAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), Arg.Any<string>(),
|
||||
Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToOrganizationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(),
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToInstallationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(),
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SendAsync_UserIdAndOrganizationIdAndInstallationIdEmpty_NoPushNotificationSent(
|
||||
SutProvider<PushController> sutProvider, Guid installationId)
|
||||
{
|
||||
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false;
|
||||
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId);
|
||||
|
||||
await sutProvider.Sut.SendAsync(new PushSendRequestModel
|
||||
{
|
||||
Type = PushType.Notification,
|
||||
UserId = null,
|
||||
OrganizationId = null,
|
||||
InstallationId = null,
|
||||
Payload = "test-payload"
|
||||
});
|
||||
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToUserAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), Arg.Any<string>(),
|
||||
Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToOrganizationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(),
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToInstallationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(),
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[RepeatingPatternBitAutoData([false, true], [false, true], [false, true])]
|
||||
public async Task SendAsync_UserIdSet_SendPayloadToUserAsync(bool haveIdentifier, bool haveDeviceId,
|
||||
bool haveOrganizationId, SutProvider<PushController> sutProvider, Guid installationId, Guid userId,
|
||||
Guid identifier, Guid deviceId)
|
||||
{
|
||||
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false;
|
||||
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId);
|
||||
|
||||
var expectedUserId = $"{installationId}_{userId}";
|
||||
var expectedIdentifier = haveIdentifier ? $"{installationId}_{identifier}" : null;
|
||||
var expectedDeviceId = haveDeviceId ? $"{installationId}_{deviceId}" : null;
|
||||
|
||||
await sutProvider.Sut.SendAsync(new PushSendRequestModel
|
||||
{
|
||||
Type = PushType.Notification,
|
||||
UserId = userId.ToString(),
|
||||
OrganizationId = haveOrganizationId ? Guid.NewGuid().ToString() : null,
|
||||
InstallationId = null,
|
||||
Payload = "test-payload",
|
||||
DeviceId = haveDeviceId ? deviceId.ToString() : null,
|
||||
Identifier = haveIdentifier ? identifier.ToString() : null,
|
||||
ClientType = ClientType.All,
|
||||
});
|
||||
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(1)
|
||||
.SendPayloadToUserAsync(expectedUserId, PushType.Notification, "test-payload", expectedIdentifier,
|
||||
expectedDeviceId, ClientType.All);
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToOrganizationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(),
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToInstallationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(),
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[RepeatingPatternBitAutoData([false, true], [false, true])]
|
||||
public async Task SendAsync_OrganizationIdSet_SendPayloadToOrganizationAsync(bool haveIdentifier, bool haveDeviceId,
|
||||
SutProvider<PushController> sutProvider, Guid installationId, Guid organizationId, Guid identifier,
|
||||
Guid deviceId)
|
||||
{
|
||||
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false;
|
||||
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId);
|
||||
|
||||
var expectedOrganizationId = $"{installationId}_{organizationId}";
|
||||
var expectedIdentifier = haveIdentifier ? $"{installationId}_{identifier}" : null;
|
||||
var expectedDeviceId = haveDeviceId ? $"{installationId}_{deviceId}" : null;
|
||||
|
||||
await sutProvider.Sut.SendAsync(new PushSendRequestModel
|
||||
{
|
||||
Type = PushType.Notification,
|
||||
UserId = null,
|
||||
OrganizationId = organizationId.ToString(),
|
||||
InstallationId = null,
|
||||
Payload = "test-payload",
|
||||
DeviceId = haveDeviceId ? deviceId.ToString() : null,
|
||||
Identifier = haveIdentifier ? identifier.ToString() : null,
|
||||
ClientType = ClientType.All,
|
||||
});
|
||||
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(1)
|
||||
.SendPayloadToOrganizationAsync(expectedOrganizationId, PushType.Notification, "test-payload",
|
||||
expectedIdentifier, expectedDeviceId, ClientType.All);
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToUserAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), Arg.Any<string>(),
|
||||
Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToInstallationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(),
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[RepeatingPatternBitAutoData([false, true], [false, true])]
|
||||
public async Task SendAsync_InstallationIdSet_SendPayloadToInstallationAsync(bool haveIdentifier, bool haveDeviceId,
|
||||
SutProvider<PushController> sutProvider, Guid installationId, Guid identifier, Guid deviceId)
|
||||
{
|
||||
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false;
|
||||
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId);
|
||||
|
||||
var expectedIdentifier = haveIdentifier ? $"{installationId}_{identifier}" : null;
|
||||
var expectedDeviceId = haveDeviceId ? $"{installationId}_{deviceId}" : null;
|
||||
|
||||
await sutProvider.Sut.SendAsync(new PushSendRequestModel
|
||||
{
|
||||
Type = PushType.Notification,
|
||||
UserId = null,
|
||||
OrganizationId = null,
|
||||
InstallationId = installationId.ToString(),
|
||||
Payload = "test-payload",
|
||||
DeviceId = haveDeviceId ? deviceId.ToString() : null,
|
||||
Identifier = haveIdentifier ? identifier.ToString() : null,
|
||||
ClientType = ClientType.All,
|
||||
});
|
||||
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(1)
|
||||
.SendPayloadToInstallationAsync(installationId.ToString(), PushType.Notification, "test-payload",
|
||||
expectedIdentifier, expectedDeviceId, ClientType.All);
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToOrganizationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(),
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToUserAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), Arg.Any<string>(),
|
||||
Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SendAsync_InstallationIdNotMatching_BadRequest(SutProvider<PushController> sutProvider,
|
||||
Guid installationId)
|
||||
{
|
||||
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false;
|
||||
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId);
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.SendAsync(new PushSendRequestModel
|
||||
{
|
||||
Type = PushType.Notification,
|
||||
UserId = null,
|
||||
OrganizationId = null,
|
||||
InstallationId = Guid.NewGuid().ToString(),
|
||||
Payload = "test-payload",
|
||||
DeviceId = null,
|
||||
Identifier = null,
|
||||
ClientType = ClientType.All,
|
||||
}));
|
||||
|
||||
Assert.Equal("InstallationId does not match current context.", exception.Message);
|
||||
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToInstallationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(),
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToOrganizationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(),
|
||||
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(0)
|
||||
.SendPayloadToUserAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), Arg.Any<string>(),
|
||||
Arg.Any<string?>(), Arg.Any<ClientType?>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(false, true)]
|
||||
[BitAutoData(false, false)]
|
||||
|
Reference in New Issue
Block a user