mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 16:42:50 -05:00
PM-10600: Organization push notifications not sending to mobile device from self-hosted.
Self-hosted instance uses relay to register the mobile device against Bitwarden Cloud Api. Only the self-hosted server knows client's organization membership, which means it needs to pass in the organization id's information to the relay. Similarly, for Bitwarden Cloud, the organizaton id will come directly from the server.
This commit is contained in:
@ -3,6 +3,7 @@ using Bit.Core.Auth.Models.Api.Request;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
@ -15,15 +16,23 @@ namespace Bit.Core.Test.Services;
|
||||
[SutProviderCustomize]
|
||||
public class DeviceServiceTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task DeviceSaveShouldUpdateRevisionDateAndPushRegistration()
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveAsync_IdProvided_UpdatedRevisionDateAndPushRegistration(Guid id, Guid userId,
|
||||
Guid organizationId1, Guid organizationId2,
|
||||
OrganizationUserOrganizationDetails organizationUserOrganizationDetails1,
|
||||
OrganizationUserOrganizationDetails organizationUserOrganizationDetails2)
|
||||
{
|
||||
organizationUserOrganizationDetails1.OrganizationId = organizationId1;
|
||||
organizationUserOrganizationDetails2.OrganizationId = organizationId2;
|
||||
|
||||
var deviceRepo = Substitute.For<IDeviceRepository>();
|
||||
var pushRepo = Substitute.For<IPushRegistrationService>();
|
||||
var deviceService = new DeviceService(deviceRepo, pushRepo);
|
||||
var organizationUserRepository = Substitute.For<IOrganizationUserRepository>();
|
||||
organizationUserRepository.GetManyDetailsByUserAsync(Arg.Any<Guid>(), Arg.Any<OrganizationUserStatusType?>())
|
||||
.Returns([organizationUserOrganizationDetails1, organizationUserOrganizationDetails2]);
|
||||
var deviceService = new DeviceService(deviceRepo, pushRepo, organizationUserRepository);
|
||||
|
||||
var id = Guid.NewGuid();
|
||||
var userId = Guid.NewGuid();
|
||||
var device = new Device
|
||||
{
|
||||
Id = id,
|
||||
@ -36,8 +45,53 @@ public class DeviceServiceTests
|
||||
await deviceService.SaveAsync(device);
|
||||
|
||||
Assert.True(device.RevisionDate - DateTime.UtcNow < TimeSpan.FromSeconds(1));
|
||||
await pushRepo.Received().CreateOrUpdateRegistrationAsync("testtoken", id.ToString(),
|
||||
userId.ToString(), "testid", DeviceType.Android);
|
||||
await pushRepo.Received(1).CreateOrUpdateRegistrationAsync("testtoken", id.ToString(),
|
||||
userId.ToString(), "testid", DeviceType.Android,
|
||||
Arg.Do<IEnumerable<string>>(organizationIds =>
|
||||
{
|
||||
var organizationIdsList = organizationIds.ToList();
|
||||
Assert.Equal(2, organizationIdsList.Count);
|
||||
Assert.Contains(organizationId1.ToString(), organizationIdsList);
|
||||
Assert.Contains(organizationId2.ToString(), organizationIdsList);
|
||||
}));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveAsync_IdNotProvided_CreatedAndPushRegistration(Guid userId, Guid organizationId1,
|
||||
Guid organizationId2,
|
||||
OrganizationUserOrganizationDetails organizationUserOrganizationDetails1,
|
||||
OrganizationUserOrganizationDetails organizationUserOrganizationDetails2)
|
||||
{
|
||||
organizationUserOrganizationDetails1.OrganizationId = organizationId1;
|
||||
organizationUserOrganizationDetails2.OrganizationId = organizationId2;
|
||||
|
||||
var deviceRepo = Substitute.For<IDeviceRepository>();
|
||||
var pushRepo = Substitute.For<IPushRegistrationService>();
|
||||
var organizationUserRepository = Substitute.For<IOrganizationUserRepository>();
|
||||
organizationUserRepository.GetManyDetailsByUserAsync(Arg.Any<Guid>(), Arg.Any<OrganizationUserStatusType?>())
|
||||
.Returns([organizationUserOrganizationDetails1, organizationUserOrganizationDetails2]);
|
||||
var deviceService = new DeviceService(deviceRepo, pushRepo, organizationUserRepository);
|
||||
|
||||
var device = new Device
|
||||
{
|
||||
Name = "test device",
|
||||
Type = DeviceType.Android,
|
||||
UserId = userId,
|
||||
PushToken = "testtoken",
|
||||
Identifier = "testid"
|
||||
};
|
||||
await deviceService.SaveAsync(device);
|
||||
|
||||
await pushRepo.Received(1).CreateOrUpdateRegistrationAsync("testtoken",
|
||||
Arg.Do<string>(id => Guid.TryParse(id, out var _)), userId.ToString(), "testid", DeviceType.Android,
|
||||
Arg.Do<IEnumerable<string>>(organizationIds =>
|
||||
{
|
||||
var organizationIdsList = organizationIds.ToList();
|
||||
Assert.Equal(2, organizationIdsList.Count);
|
||||
Assert.Contains(organizationId1.ToString(), organizationIdsList);
|
||||
Assert.Contains(organizationId2.ToString(), organizationIdsList);
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -61,12 +115,7 @@ public class DeviceServiceTests
|
||||
|
||||
sutProvider.GetDependency<IDeviceRepository>()
|
||||
.GetManyByUserIdAsync(currentUserId)
|
||||
.Returns(new List<Device>
|
||||
{
|
||||
deviceOne,
|
||||
deviceTwo,
|
||||
deviceThree,
|
||||
});
|
||||
.Returns(new List<Device> { deviceOne, deviceTwo, deviceThree, });
|
||||
|
||||
var currentDeviceModel = new DeviceKeysUpdateRequestModel
|
||||
{
|
||||
@ -84,7 +133,8 @@ public class DeviceServiceTests
|
||||
},
|
||||
};
|
||||
|
||||
await sutProvider.Sut.UpdateDevicesTrustAsync("current_device", currentUserId, currentDeviceModel, alteredDeviceModels);
|
||||
await sutProvider.Sut.UpdateDevicesTrustAsync("current_device", currentUserId, currentDeviceModel,
|
||||
alteredDeviceModels);
|
||||
|
||||
// Updating trust, "current" or "other" only needs to change the EncryptedPublicKey & EncryptedUserKey
|
||||
await sutProvider.GetDependency<IDeviceRepository>()
|
||||
@ -148,11 +198,7 @@ public class DeviceServiceTests
|
||||
|
||||
sutProvider.GetDependency<IDeviceRepository>()
|
||||
.GetManyByUserIdAsync(currentUserId)
|
||||
.Returns(new List<Device>
|
||||
{
|
||||
deviceOne,
|
||||
deviceTwo,
|
||||
});
|
||||
.Returns(new List<Device> { deviceOne, deviceTwo, });
|
||||
|
||||
var currentDeviceModel = new DeviceKeysUpdateRequestModel
|
||||
{
|
||||
@ -170,7 +216,8 @@ public class DeviceServiceTests
|
||||
},
|
||||
};
|
||||
|
||||
await sutProvider.Sut.UpdateDevicesTrustAsync("current_device", currentUserId, currentDeviceModel, alteredDeviceModels);
|
||||
await sutProvider.Sut.UpdateDevicesTrustAsync("current_device", currentUserId, currentDeviceModel,
|
||||
alteredDeviceModels);
|
||||
|
||||
// Check that UpsertAsync was called for the trusted device
|
||||
await sutProvider.GetDependency<IDeviceRepository>()
|
||||
@ -202,11 +249,7 @@ public class DeviceServiceTests
|
||||
|
||||
sutProvider.GetDependency<IDeviceRepository>()
|
||||
.GetManyByUserIdAsync(currentUserId)
|
||||
.Returns(new List<Device>
|
||||
{
|
||||
deviceOne,
|
||||
deviceTwo,
|
||||
});
|
||||
.Returns(new List<Device> { deviceOne, deviceTwo, });
|
||||
|
||||
var currentDeviceModel = new DeviceKeysUpdateRequestModel
|
||||
{
|
||||
@ -236,11 +279,7 @@ public class DeviceServiceTests
|
||||
|
||||
sutProvider.GetDependency<IDeviceRepository>()
|
||||
.GetManyByUserIdAsync(currentUserId)
|
||||
.Returns(new List<Device>
|
||||
{
|
||||
deviceOne,
|
||||
deviceTwo,
|
||||
});
|
||||
.Returns(new List<Device> { deviceOne, deviceTwo, });
|
||||
|
||||
var currentDeviceModel = new DeviceKeysUpdateRequestModel
|
||||
{
|
||||
@ -259,6 +298,7 @@ public class DeviceServiceTests
|
||||
};
|
||||
|
||||
await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.UpdateDevicesTrustAsync("current_device", currentUserId, currentDeviceModel, alteredDeviceModels));
|
||||
sutProvider.Sut.UpdateDevicesTrustAsync("current_device", currentUserId, currentDeviceModel,
|
||||
alteredDeviceModels));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user