1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-29 08:42:19 -05:00
Addison Beck cd7c4bf6ce
chore: move Installation and Push to platform's domain folders (#5085)
* chore: set up a `CODEOWNERS` space for platform

* chore: move sql objects for `Installation` to platform's domain

* chore: move `Installation` and `PushRelay` code to platform's domain
2025-01-06 18:10:53 +01:00

117 lines
3.9 KiB
C#

using Bit.Core.Auth.Models.Api.Request;
using Bit.Core.Auth.Utilities;
using Bit.Core.Entities;
using Bit.Core.Exceptions;
using Bit.Core.Platform.Push;
using Bit.Core.Repositories;
namespace Bit.Core.Services;
public class DeviceService : IDeviceService
{
private readonly IDeviceRepository _deviceRepository;
private readonly IPushRegistrationService _pushRegistrationService;
public DeviceService(
IDeviceRepository deviceRepository,
IPushRegistrationService pushRegistrationService)
{
_deviceRepository = deviceRepository;
_pushRegistrationService = pushRegistrationService;
}
public async Task SaveAsync(Device device)
{
if (device.Id == default(Guid))
{
await _deviceRepository.CreateAsync(device);
}
else
{
device.RevisionDate = DateTime.UtcNow;
await _deviceRepository.ReplaceAsync(device);
}
await _pushRegistrationService.CreateOrUpdateRegistrationAsync(device.PushToken, device.Id.ToString(),
device.UserId.ToString(), device.Identifier, device.Type);
}
public async Task ClearTokenAsync(Device device)
{
await _deviceRepository.ClearPushTokenAsync(device.Id);
await _pushRegistrationService.DeleteRegistrationAsync(device.Id.ToString());
}
public async Task DeactivateAsync(Device device)
{
// already deactivated
if (!device.Active)
{
return;
}
device.Active = false;
device.RevisionDate = DateTime.UtcNow;
await _deviceRepository.UpsertAsync(device);
await _pushRegistrationService.DeleteRegistrationAsync(device.Id.ToString());
}
public async Task UpdateDevicesTrustAsync(string currentDeviceIdentifier,
Guid currentUserId,
DeviceKeysUpdateRequestModel currentDeviceUpdate,
IEnumerable<OtherDeviceKeysUpdateRequestModel> alteredDevices)
{
var existingDevices = await _deviceRepository.GetManyByUserIdAsync(currentUserId);
var currentDevice = existingDevices.FirstOrDefault(d => d.Identifier == currentDeviceIdentifier);
if (currentDevice == null)
{
throw new NotFoundException();
}
existingDevices.Remove(currentDevice);
var alterDeviceKeysDict = alteredDevices.ToDictionary(d => d.DeviceId);
if (alterDeviceKeysDict.ContainsKey(currentDevice.Id))
{
throw new BadRequestException("Current device can not be an optional rotation.");
}
currentDevice.EncryptedPublicKey = currentDeviceUpdate.EncryptedPublicKey;
currentDevice.EncryptedUserKey = currentDeviceUpdate.EncryptedUserKey;
await _deviceRepository.UpsertAsync(currentDevice);
foreach (var device in existingDevices)
{
if (!device.IsTrusted())
{
// You can't update the trust of a device that isn't trusted to begin with
// should we throw and consider this a BadRequest? If we want to consider it a invalid request
// we need to check that information before we enter this foreach, we don't want to partially complete
// this process.
continue;
}
if (alterDeviceKeysDict.TryGetValue(device.Id, out var updateRequest))
{
// An update to this device was requested
device.EncryptedPublicKey = updateRequest.EncryptedPublicKey;
device.EncryptedUserKey = updateRequest.EncryptedUserKey;
}
else
{
// No update to this device requested, just untrust it
device.EncryptedUserKey = null;
device.EncryptedPublicKey = null;
device.EncryptedPrivateKey = null;
}
await _deviceRepository.UpsertAsync(device);
}
}
}