1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-04 17:42:49 -05:00

record installation devices

This commit is contained in:
Kyle Spearrin
2019-03-19 00:39:03 -04:00
parent 11fafa4a92
commit 01a293cf76
15 changed files with 255 additions and 36 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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)

View File

@ -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,

View File

@ -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);

View File

@ -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();
}