mirror of
https://github.com/bitwarden/server.git
synced 2025-07-05 10:02:47 -05:00
record installation devices
This commit is contained in:
@ -19,7 +19,8 @@ namespace Bit.Core.Services
|
||||
Task PushSyncOrgKeysAsync(Guid userId);
|
||||
Task PushSyncSettingsAsync(Guid userId);
|
||||
Task PushLogOutAsync(Guid userId);
|
||||
Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier);
|
||||
Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier);
|
||||
Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier, string deviceId = null);
|
||||
Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||
string deviceId = null);
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ namespace Bit.Core.Services
|
||||
private async Task SendMessageAsync<T>(PushType type, T payload, bool excludeCurrentContext)
|
||||
{
|
||||
var contextId = GetContextIdentifier(excludeCurrentContext);
|
||||
var message = JsonConvert.SerializeObject(new PushNotificationData<T>(type, payload, contextId),
|
||||
var message = JsonConvert.SerializeObject(new PushNotificationData<T>(type, payload, contextId),
|
||||
_jsonSettings);
|
||||
var queueMessage = new CloudQueueMessage(message);
|
||||
await _queue.AddMessageAsync(queueMessage);
|
||||
@ -159,13 +159,15 @@ namespace Bit.Core.Services
|
||||
return currentContext?.DeviceIdentifier;
|
||||
}
|
||||
|
||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier)
|
||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
// Noop
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier)
|
||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
// Noop
|
||||
return Task.FromResult(0);
|
||||
|
@ -6,14 +6,19 @@ using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Bit.Core.Repositories;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class MultiServicePushNotificationService : IPushNotificationService
|
||||
{
|
||||
private readonly List<IPushNotificationService> _services = new List<IPushNotificationService>();
|
||||
private readonly IDeviceRepository _deviceRepository;
|
||||
private readonly IInstallationDeviceRepository _installationDeviceRepository;
|
||||
|
||||
public MultiServicePushNotificationService(
|
||||
IDeviceRepository deviceRepository,
|
||||
IInstallationDeviceRepository installationDeviceRepository,
|
||||
GlobalSettings globalSettings,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
ILogger<RelayPushNotificationService> relayLogger,
|
||||
@ -25,7 +30,8 @@ namespace Bit.Core.Services
|
||||
globalSettings.Installation?.Id != null &&
|
||||
CoreHelpers.SettingHasValue(globalSettings.Installation?.Key))
|
||||
{
|
||||
_services.Add(new RelayPushNotificationService(globalSettings, httpContextAccessor, relayLogger));
|
||||
_services.Add(new RelayPushNotificationService(_deviceRepository, globalSettings,
|
||||
httpContextAccessor, relayLogger));
|
||||
}
|
||||
if(CoreHelpers.SettingHasValue(globalSettings.InternalIdentityKey) &&
|
||||
CoreHelpers.SettingHasValue(globalSettings.BaseServiceUri.InternalNotifications))
|
||||
@ -38,13 +44,17 @@ namespace Bit.Core.Services
|
||||
{
|
||||
if(CoreHelpers.SettingHasValue(globalSettings.NotificationHub.ConnectionString))
|
||||
{
|
||||
_services.Add(new NotificationHubPushNotificationService(globalSettings, httpContextAccessor));
|
||||
_services.Add(new NotificationHubPushNotificationService(_installationDeviceRepository,
|
||||
globalSettings, httpContextAccessor));
|
||||
}
|
||||
if(CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
|
||||
{
|
||||
_services.Add(new AzureQueuePushNotificationService(globalSettings, httpContextAccessor));
|
||||
}
|
||||
}
|
||||
|
||||
_deviceRepository = deviceRepository;
|
||||
_installationDeviceRepository = installationDeviceRepository;
|
||||
}
|
||||
|
||||
public Task PushSyncCipherCreateAsync(Cipher cipher, IEnumerable<Guid> collectionIds)
|
||||
@ -113,15 +123,17 @@ namespace Bit.Core.Services
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier)
|
||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
PushToServices((s) => s.SendPayloadToUserAsync(userId, type, payload, identifier));
|
||||
PushToServices((s) => s.SendPayloadToUserAsync(userId, type, payload, identifier, deviceId));
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier)
|
||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
PushToServices((s) => s.SendPayloadToOrganizationAsync(orgId, type, payload, identifier));
|
||||
PushToServices((s) => s.SendPayloadToOrganizationAsync(orgId, type, payload, identifier, deviceId));
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
|
@ -7,20 +7,25 @@ using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Bit.Core.Models;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Repositories;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class NotificationHubPushNotificationService : IPushNotificationService
|
||||
{
|
||||
private readonly IInstallationDeviceRepository _installationDeviceRepository;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
private NotificationHubClient _client = null;
|
||||
|
||||
public NotificationHubPushNotificationService(
|
||||
IInstallationDeviceRepository installationDeviceRepository,
|
||||
GlobalSettings globalSettings,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
_installationDeviceRepository = installationDeviceRepository;
|
||||
_globalSettings = globalSettings;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_client = NotificationHubClient.CreateClientFromConnectionString(
|
||||
@ -141,16 +146,26 @@ namespace Bit.Core.Services
|
||||
await SendPayloadToUserAsync(orgId.ToString(), type, payload, GetContextIdentifier(excludeCurrentContext));
|
||||
}
|
||||
|
||||
public async Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier)
|
||||
public async Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
var tag = BuildTag($"template:payload_userId:{userId}", identifier);
|
||||
await SendPayloadAsync(tag, type, payload);
|
||||
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
{
|
||||
await _installationDeviceRepository.UpsertAsync(new InstallationDeviceEntity(deviceId));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier)
|
||||
public async Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
var tag = BuildTag($"template:payload && organizationId:{orgId}", identifier);
|
||||
await SendPayloadAsync(tag, type, payload);
|
||||
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
{
|
||||
await _installationDeviceRepository.UpsertAsync(new InstallationDeviceEntity(deviceId));
|
||||
}
|
||||
}
|
||||
|
||||
private string GetContextIdentifier(bool excludeCurrentContext)
|
||||
|
@ -4,18 +4,23 @@ using Microsoft.Azure.NotificationHubs;
|
||||
using Bit.Core.Enums;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Repositories;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class NotificationHubPushRegistrationService : IPushRegistrationService
|
||||
{
|
||||
private readonly IInstallationDeviceRepository _installationDeviceRepository;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
|
||||
|
||||
private NotificationHubClient _client = null;
|
||||
|
||||
public NotificationHubPushRegistrationService(
|
||||
IInstallationDeviceRepository installationDeviceRepository,
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
_installationDeviceRepository = installationDeviceRepository;
|
||||
_globalSettings = globalSettings;
|
||||
_client = NotificationHubClient.CreateClientFromConnectionString(
|
||||
_globalSettings.NotificationHub.ConnectionString,
|
||||
@ -83,6 +88,10 @@ namespace Bit.Core.Services
|
||||
userId, identifier);
|
||||
|
||||
await _client.CreateOrUpdateInstallationAsync(installation);
|
||||
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
{
|
||||
await _installationDeviceRepository.UpsertAsync(new InstallationDeviceEntity(deviceId));
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildInstallationTemplate(Installation installation, string templateId, string templateBody,
|
||||
@ -118,6 +127,10 @@ namespace Bit.Core.Services
|
||||
try
|
||||
{
|
||||
await _client.DeleteInstallationAsync(deviceId);
|
||||
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||
{
|
||||
await _installationDeviceRepository.DeleteAsync(new InstallationDeviceEntity(deviceId));
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -131,12 +144,22 @@ namespace Bit.Core.Services
|
||||
public async Task AddUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId)
|
||||
{
|
||||
await PatchTagsForUserDevicesAsync(deviceIds, UpdateOperationType.Add, $"organizationId:{organizationId}");
|
||||
if(deviceIds.Any() && InstallationDeviceEntity.IsInstallationDeviceId(deviceIds.First()))
|
||||
{
|
||||
var entities = deviceIds.Select(e => new InstallationDeviceEntity(e));
|
||||
await _installationDeviceRepository.UpsertManyAsync(entities.ToList());
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId)
|
||||
{
|
||||
await PatchTagsForUserDevicesAsync(deviceIds, UpdateOperationType.Remove,
|
||||
$"organizationId:{organizationId}");
|
||||
if(deviceIds.Any() && InstallationDeviceEntity.IsInstallationDeviceId(deviceIds.First()))
|
||||
{
|
||||
var entities = deviceIds.Select(e => new InstallationDeviceEntity(e));
|
||||
await _installationDeviceRepository.UpsertManyAsync(entities.ToList());
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PatchTagsForUserDevicesAsync(IEnumerable<string> deviceIds, UpdateOperationType op,
|
||||
|
@ -161,13 +161,15 @@ namespace Bit.Core.Services
|
||||
return currentContext?.DeviceIdentifier;
|
||||
}
|
||||
|
||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier)
|
||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
// Noop
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier)
|
||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
// Noop
|
||||
return Task.FromResult(0);
|
||||
|
@ -8,15 +8,18 @@ using System.Net.Http;
|
||||
using Bit.Core.Models.Api;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Generic;
|
||||
using Bit.Core.Repositories;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class RelayPushNotificationService : BaseIdentityClientService, IPushNotificationService
|
||||
{
|
||||
private readonly IDeviceRepository _deviceRepository;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly ILogger<RelayPushNotificationService> _logger;
|
||||
|
||||
public RelayPushNotificationService(
|
||||
IDeviceRepository deviceRepository,
|
||||
GlobalSettings globalSettings,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
ILogger<RelayPushNotificationService> logger)
|
||||
@ -28,6 +31,7 @@ namespace Bit.Core.Services
|
||||
globalSettings.Installation.Key,
|
||||
logger)
|
||||
{
|
||||
_deviceRepository = deviceRepository;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_logger = logger;
|
||||
}
|
||||
@ -143,12 +147,8 @@ namespace Bit.Core.Services
|
||||
Type = type,
|
||||
Payload = payload
|
||||
};
|
||||
|
||||
if(excludeCurrentContext)
|
||||
{
|
||||
ExcludeCurrentContext(request);
|
||||
}
|
||||
|
||||
|
||||
await AddCurrentContextAsync(request, excludeCurrentContext);
|
||||
await SendAsync(HttpMethod.Post, "push/send", request);
|
||||
}
|
||||
|
||||
@ -161,30 +161,36 @@ namespace Bit.Core.Services
|
||||
Payload = payload
|
||||
};
|
||||
|
||||
if(excludeCurrentContext)
|
||||
{
|
||||
ExcludeCurrentContext(request);
|
||||
}
|
||||
|
||||
await AddCurrentContextAsync(request, excludeCurrentContext);
|
||||
await SendAsync(HttpMethod.Post, "push/send", request);
|
||||
}
|
||||
|
||||
private void ExcludeCurrentContext(PushSendRequestModel request)
|
||||
private async Task AddCurrentContextAsync(PushSendRequestModel request, bool addIdentifier)
|
||||
{
|
||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
||||
RequestServices.GetService(typeof(CurrentContext)) as CurrentContext;
|
||||
RequestServices.GetService(typeof(CurrentContext)) as CurrentContext;
|
||||
if(!string.IsNullOrWhiteSpace(currentContext?.DeviceIdentifier))
|
||||
{
|
||||
request.Identifier = currentContext.DeviceIdentifier;
|
||||
var device = await _deviceRepository.GetByIdentifierAsync(currentContext.DeviceIdentifier);
|
||||
if(device != null)
|
||||
{
|
||||
request.DeviceId = device.Id.ToString();
|
||||
}
|
||||
if(addIdentifier)
|
||||
{
|
||||
request.Identifier = currentContext.DeviceIdentifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier)
|
||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier)
|
||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -63,12 +63,14 @@ namespace Bit.Core.Services
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier)
|
||||
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier)
|
||||
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
|
||||
string deviceId = null)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user