mirror of
https://github.com/bitwarden/server.git
synced 2025-04-08 06:28:14 -05:00
record installation devices
This commit is contained in:
parent
11fafa4a92
commit
01a293cf76
@ -76,12 +76,12 @@ namespace Bit.Api.Controllers
|
|||||||
if(!string.IsNullOrWhiteSpace(model.UserId))
|
if(!string.IsNullOrWhiteSpace(model.UserId))
|
||||||
{
|
{
|
||||||
await _pushNotificationService.SendPayloadToUserAsync(Prefix(model.UserId),
|
await _pushNotificationService.SendPayloadToUserAsync(Prefix(model.UserId),
|
||||||
model.Type.Value, model.Payload, Prefix(model.Identifier));
|
model.Type.Value, model.Payload, Prefix(model.Identifier), Prefix(model.DeviceId));
|
||||||
}
|
}
|
||||||
else if(!string.IsNullOrWhiteSpace(model.OrganizationId))
|
else if(!string.IsNullOrWhiteSpace(model.OrganizationId))
|
||||||
{
|
{
|
||||||
await _pushNotificationService.SendPayloadToOrganizationAsync(Prefix(model.OrganizationId),
|
await _pushNotificationService.SendPayloadToOrganizationAsync(Prefix(model.OrganizationId),
|
||||||
model.Type.Value, model.Payload, Prefix(model.Identifier));
|
model.Type.Value, model.Payload, Prefix(model.Identifier), Prefix(model.DeviceId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ namespace Bit.Core.Models.Api
|
|||||||
{
|
{
|
||||||
public string UserId { get; set; }
|
public string UserId { get; set; }
|
||||||
public string OrganizationId { get; set; }
|
public string OrganizationId { get; set; }
|
||||||
|
public string DeviceId { get; set; }
|
||||||
public string Identifier { get; set; }
|
public string Identifier { get; set; }
|
||||||
[Required]
|
[Required]
|
||||||
public PushType? Type { get; set; }
|
public PushType? Type { get; set; }
|
||||||
|
36
src/Core/Models/Data/InstallationDeviceEntity.cs
Normal file
36
src/Core/Models/Data/InstallationDeviceEntity.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.WindowsAzure.Storage.Table;
|
||||||
|
|
||||||
|
namespace Bit.Core.Models.Data
|
||||||
|
{
|
||||||
|
public class InstallationDeviceEntity : TableEntity
|
||||||
|
{
|
||||||
|
public InstallationDeviceEntity() { }
|
||||||
|
|
||||||
|
public InstallationDeviceEntity(Guid installationId, Guid deviceId)
|
||||||
|
{
|
||||||
|
PartitionKey = installationId.ToString();
|
||||||
|
RowKey = deviceId.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstallationDeviceEntity(string prefixedDeviceId)
|
||||||
|
{
|
||||||
|
var parts = prefixedDeviceId.Split("_");
|
||||||
|
if(parts.Length < 2)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Not enough parts.");
|
||||||
|
}
|
||||||
|
if(!Guid.TryParse(parts[0], out var installationId) || !Guid.TryParse(parts[1], out var deviceId))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Could not parse parts.");
|
||||||
|
}
|
||||||
|
PartitionKey = parts[0];
|
||||||
|
RowKey = parts[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsInstallationDeviceId(string deviceId)
|
||||||
|
{
|
||||||
|
return deviceId != null && deviceId.Length == 73 && deviceId[36] == '_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
src/Core/Repositories/IInstallationDeviceRepository.cs
Normal file
13
src/Core/Repositories/IInstallationDeviceRepository.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Models.Data;
|
||||||
|
|
||||||
|
namespace Bit.Core.Repositories
|
||||||
|
{
|
||||||
|
public interface IInstallationDeviceRepository
|
||||||
|
{
|
||||||
|
Task UpsertAsync(InstallationDeviceEntity entity);
|
||||||
|
Task UpsertManyAsync(IList<InstallationDeviceEntity> entities);
|
||||||
|
Task DeleteAsync(InstallationDeviceEntity entity);
|
||||||
|
}
|
||||||
|
}
|
24
src/Core/Repositories/Noop/InstallationDeviceRepository.cs
Normal file
24
src/Core/Repositories/Noop/InstallationDeviceRepository.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Models.Data;
|
||||||
|
|
||||||
|
namespace Bit.Core.Repositories.Noop
|
||||||
|
{
|
||||||
|
public class InstallationDeviceRepository : IInstallationDeviceRepository
|
||||||
|
{
|
||||||
|
public Task UpsertAsync(InstallationDeviceEntity entity)
|
||||||
|
{
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task UpsertManyAsync(IList<InstallationDeviceEntity> entities)
|
||||||
|
{
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteAsync(InstallationDeviceEntity entity)
|
||||||
|
{
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Models.Data;
|
||||||
|
using Microsoft.WindowsAzure.Storage;
|
||||||
|
using Microsoft.WindowsAzure.Storage.Table;
|
||||||
|
|
||||||
|
namespace Bit.Core.Repositories.TableStorage
|
||||||
|
{
|
||||||
|
public class InstallationDeviceRepository : IInstallationDeviceRepository
|
||||||
|
{
|
||||||
|
private readonly CloudTable _table;
|
||||||
|
|
||||||
|
public InstallationDeviceRepository(GlobalSettings globalSettings)
|
||||||
|
: this(globalSettings.Events.ConnectionString)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public InstallationDeviceRepository(string storageConnectionString)
|
||||||
|
{
|
||||||
|
var storageAccount = CloudStorageAccount.Parse(storageConnectionString);
|
||||||
|
var tableClient = storageAccount.CreateCloudTableClient();
|
||||||
|
_table = tableClient.GetTableReference("installationdevice");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpsertAsync(InstallationDeviceEntity entity)
|
||||||
|
{
|
||||||
|
await _table.ExecuteAsync(TableOperation.InsertOrReplace(entity));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpsertManyAsync(IList<InstallationDeviceEntity> entities)
|
||||||
|
{
|
||||||
|
if(!entities?.Any() ?? true)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entities.Count == 1)
|
||||||
|
{
|
||||||
|
await UpsertAsync(entities.First());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var entityGroups = entities.GroupBy(ent => ent.PartitionKey);
|
||||||
|
foreach(var group in entityGroups)
|
||||||
|
{
|
||||||
|
var groupEntities = group.ToList();
|
||||||
|
if(groupEntities.Count == 1)
|
||||||
|
{
|
||||||
|
await UpsertAsync(groupEntities.First());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A batch insert can only contain 100 entities at a time
|
||||||
|
var iterations = groupEntities.Count / 100;
|
||||||
|
for(var i = 0; i <= iterations; i++)
|
||||||
|
{
|
||||||
|
var batch = new TableBatchOperation();
|
||||||
|
var batchEntities = groupEntities.Skip(i * 100).Take(100);
|
||||||
|
if(!batchEntities.Any())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(var entity in batchEntities)
|
||||||
|
{
|
||||||
|
batch.InsertOrReplace(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
await _table.ExecuteBatchAsync(batch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAsync(InstallationDeviceEntity entity)
|
||||||
|
{
|
||||||
|
await _table.ExecuteAsync(TableOperation.Delete(entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,8 @@ namespace Bit.Core.Services
|
|||||||
Task PushSyncOrgKeysAsync(Guid userId);
|
Task PushSyncOrgKeysAsync(Guid userId);
|
||||||
Task PushSyncSettingsAsync(Guid userId);
|
Task PushSyncSettingsAsync(Guid userId);
|
||||||
Task PushLogOutAsync(Guid userId);
|
Task PushLogOutAsync(Guid userId);
|
||||||
Task SendPayloadToUserAsync(string userId, 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);
|
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)
|
private async Task SendMessageAsync<T>(PushType type, T payload, bool excludeCurrentContext)
|
||||||
{
|
{
|
||||||
var contextId = GetContextIdentifier(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);
|
_jsonSettings);
|
||||||
var queueMessage = new CloudQueueMessage(message);
|
var queueMessage = new CloudQueueMessage(message);
|
||||||
await _queue.AddMessageAsync(queueMessage);
|
await _queue.AddMessageAsync(queueMessage);
|
||||||
@ -159,13 +159,15 @@ namespace Bit.Core.Services
|
|||||||
return currentContext?.DeviceIdentifier;
|
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
|
// Noop
|
||||||
return Task.FromResult(0);
|
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
|
// Noop
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
|
@ -6,14 +6,19 @@ using System.Collections.Generic;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
public class MultiServicePushNotificationService : IPushNotificationService
|
public class MultiServicePushNotificationService : IPushNotificationService
|
||||||
{
|
{
|
||||||
private readonly List<IPushNotificationService> _services = new List<IPushNotificationService>();
|
private readonly List<IPushNotificationService> _services = new List<IPushNotificationService>();
|
||||||
|
private readonly IDeviceRepository _deviceRepository;
|
||||||
|
private readonly IInstallationDeviceRepository _installationDeviceRepository;
|
||||||
|
|
||||||
public MultiServicePushNotificationService(
|
public MultiServicePushNotificationService(
|
||||||
|
IDeviceRepository deviceRepository,
|
||||||
|
IInstallationDeviceRepository installationDeviceRepository,
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
IHttpContextAccessor httpContextAccessor,
|
IHttpContextAccessor httpContextAccessor,
|
||||||
ILogger<RelayPushNotificationService> relayLogger,
|
ILogger<RelayPushNotificationService> relayLogger,
|
||||||
@ -25,7 +30,8 @@ namespace Bit.Core.Services
|
|||||||
globalSettings.Installation?.Id != null &&
|
globalSettings.Installation?.Id != null &&
|
||||||
CoreHelpers.SettingHasValue(globalSettings.Installation?.Key))
|
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) &&
|
if(CoreHelpers.SettingHasValue(globalSettings.InternalIdentityKey) &&
|
||||||
CoreHelpers.SettingHasValue(globalSettings.BaseServiceUri.InternalNotifications))
|
CoreHelpers.SettingHasValue(globalSettings.BaseServiceUri.InternalNotifications))
|
||||||
@ -38,13 +44,17 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
if(CoreHelpers.SettingHasValue(globalSettings.NotificationHub.ConnectionString))
|
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))
|
if(CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
|
||||||
{
|
{
|
||||||
_services.Add(new AzureQueuePushNotificationService(globalSettings, httpContextAccessor));
|
_services.Add(new AzureQueuePushNotificationService(globalSettings, httpContextAccessor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_deviceRepository = deviceRepository;
|
||||||
|
_installationDeviceRepository = installationDeviceRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task PushSyncCipherCreateAsync(Cipher cipher, IEnumerable<Guid> collectionIds)
|
public Task PushSyncCipherCreateAsync(Cipher cipher, IEnumerable<Guid> collectionIds)
|
||||||
@ -113,15 +123,17 @@ namespace Bit.Core.Services
|
|||||||
return Task.FromResult(0);
|
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);
|
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);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,20 +7,25 @@ using Newtonsoft.Json;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
|
using Bit.Core.Models.Data;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
public class NotificationHubPushNotificationService : IPushNotificationService
|
public class NotificationHubPushNotificationService : IPushNotificationService
|
||||||
{
|
{
|
||||||
|
private readonly IInstallationDeviceRepository _installationDeviceRepository;
|
||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
|
||||||
private NotificationHubClient _client = null;
|
private NotificationHubClient _client = null;
|
||||||
|
|
||||||
public NotificationHubPushNotificationService(
|
public NotificationHubPushNotificationService(
|
||||||
|
IInstallationDeviceRepository installationDeviceRepository,
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
IHttpContextAccessor httpContextAccessor)
|
IHttpContextAccessor httpContextAccessor)
|
||||||
{
|
{
|
||||||
|
_installationDeviceRepository = installationDeviceRepository;
|
||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
_httpContextAccessor = httpContextAccessor;
|
_httpContextAccessor = httpContextAccessor;
|
||||||
_client = NotificationHubClient.CreateClientFromConnectionString(
|
_client = NotificationHubClient.CreateClientFromConnectionString(
|
||||||
@ -141,16 +146,26 @@ namespace Bit.Core.Services
|
|||||||
await SendPayloadToUserAsync(orgId.ToString(), type, payload, GetContextIdentifier(excludeCurrentContext));
|
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);
|
var tag = BuildTag($"template:payload_userId:{userId}", identifier);
|
||||||
await SendPayloadAsync(tag, type, payload);
|
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);
|
var tag = BuildTag($"template:payload && organizationId:{orgId}", identifier);
|
||||||
await SendPayloadAsync(tag, type, payload);
|
await SendPayloadAsync(tag, type, payload);
|
||||||
|
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||||
|
{
|
||||||
|
await _installationDeviceRepository.UpsertAsync(new InstallationDeviceEntity(deviceId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetContextIdentifier(bool excludeCurrentContext)
|
private string GetContextIdentifier(bool excludeCurrentContext)
|
||||||
|
@ -4,18 +4,23 @@ using Microsoft.Azure.NotificationHubs;
|
|||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System;
|
using System;
|
||||||
|
using Bit.Core.Models.Data;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
public class NotificationHubPushRegistrationService : IPushRegistrationService
|
public class NotificationHubPushRegistrationService : IPushRegistrationService
|
||||||
{
|
{
|
||||||
|
private readonly IInstallationDeviceRepository _installationDeviceRepository;
|
||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
|
|
||||||
private NotificationHubClient _client = null;
|
private NotificationHubClient _client = null;
|
||||||
|
|
||||||
public NotificationHubPushRegistrationService(
|
public NotificationHubPushRegistrationService(
|
||||||
|
IInstallationDeviceRepository installationDeviceRepository,
|
||||||
GlobalSettings globalSettings)
|
GlobalSettings globalSettings)
|
||||||
{
|
{
|
||||||
|
_installationDeviceRepository = installationDeviceRepository;
|
||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
_client = NotificationHubClient.CreateClientFromConnectionString(
|
_client = NotificationHubClient.CreateClientFromConnectionString(
|
||||||
_globalSettings.NotificationHub.ConnectionString,
|
_globalSettings.NotificationHub.ConnectionString,
|
||||||
@ -83,6 +88,10 @@ namespace Bit.Core.Services
|
|||||||
userId, identifier);
|
userId, identifier);
|
||||||
|
|
||||||
await _client.CreateOrUpdateInstallationAsync(installation);
|
await _client.CreateOrUpdateInstallationAsync(installation);
|
||||||
|
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||||
|
{
|
||||||
|
await _installationDeviceRepository.UpsertAsync(new InstallationDeviceEntity(deviceId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BuildInstallationTemplate(Installation installation, string templateId, string templateBody,
|
private void BuildInstallationTemplate(Installation installation, string templateId, string templateBody,
|
||||||
@ -118,6 +127,10 @@ namespace Bit.Core.Services
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _client.DeleteInstallationAsync(deviceId);
|
await _client.DeleteInstallationAsync(deviceId);
|
||||||
|
if(InstallationDeviceEntity.IsInstallationDeviceId(deviceId))
|
||||||
|
{
|
||||||
|
await _installationDeviceRepository.DeleteAsync(new InstallationDeviceEntity(deviceId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
@ -131,12 +144,22 @@ namespace Bit.Core.Services
|
|||||||
public async Task AddUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId)
|
public async Task AddUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId)
|
||||||
{
|
{
|
||||||
await PatchTagsForUserDevicesAsync(deviceIds, UpdateOperationType.Add, $"organizationId:{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)
|
public async Task DeleteUserRegistrationOrganizationAsync(IEnumerable<string> deviceIds, string organizationId)
|
||||||
{
|
{
|
||||||
await PatchTagsForUserDevicesAsync(deviceIds, UpdateOperationType.Remove,
|
await PatchTagsForUserDevicesAsync(deviceIds, UpdateOperationType.Remove,
|
||||||
$"organizationId:{organizationId}");
|
$"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,
|
private async Task PatchTagsForUserDevicesAsync(IEnumerable<string> deviceIds, UpdateOperationType op,
|
||||||
|
@ -161,13 +161,15 @@ namespace Bit.Core.Services
|
|||||||
return currentContext?.DeviceIdentifier;
|
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
|
// Noop
|
||||||
return Task.FromResult(0);
|
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
|
// Noop
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
|
@ -8,15 +8,18 @@ using System.Net.Http;
|
|||||||
using Bit.Core.Models.Api;
|
using Bit.Core.Models.Api;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
|
||||||
namespace Bit.Core.Services
|
namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
public class RelayPushNotificationService : BaseIdentityClientService, IPushNotificationService
|
public class RelayPushNotificationService : BaseIdentityClientService, IPushNotificationService
|
||||||
{
|
{
|
||||||
|
private readonly IDeviceRepository _deviceRepository;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
private readonly ILogger<RelayPushNotificationService> _logger;
|
private readonly ILogger<RelayPushNotificationService> _logger;
|
||||||
|
|
||||||
public RelayPushNotificationService(
|
public RelayPushNotificationService(
|
||||||
|
IDeviceRepository deviceRepository,
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
IHttpContextAccessor httpContextAccessor,
|
IHttpContextAccessor httpContextAccessor,
|
||||||
ILogger<RelayPushNotificationService> logger)
|
ILogger<RelayPushNotificationService> logger)
|
||||||
@ -28,6 +31,7 @@ namespace Bit.Core.Services
|
|||||||
globalSettings.Installation.Key,
|
globalSettings.Installation.Key,
|
||||||
logger)
|
logger)
|
||||||
{
|
{
|
||||||
|
_deviceRepository = deviceRepository;
|
||||||
_httpContextAccessor = httpContextAccessor;
|
_httpContextAccessor = httpContextAccessor;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
@ -143,12 +147,8 @@ namespace Bit.Core.Services
|
|||||||
Type = type,
|
Type = type,
|
||||||
Payload = payload
|
Payload = payload
|
||||||
};
|
};
|
||||||
|
|
||||||
if(excludeCurrentContext)
|
await AddCurrentContextAsync(request, excludeCurrentContext);
|
||||||
{
|
|
||||||
ExcludeCurrentContext(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
await SendAsync(HttpMethod.Post, "push/send", request);
|
await SendAsync(HttpMethod.Post, "push/send", request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,30 +161,36 @@ namespace Bit.Core.Services
|
|||||||
Payload = payload
|
Payload = payload
|
||||||
};
|
};
|
||||||
|
|
||||||
if(excludeCurrentContext)
|
await AddCurrentContextAsync(request, excludeCurrentContext);
|
||||||
{
|
|
||||||
ExcludeCurrentContext(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
await SendAsync(HttpMethod.Post, "push/send", request);
|
await SendAsync(HttpMethod.Post, "push/send", request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExcludeCurrentContext(PushSendRequestModel request)
|
private async Task AddCurrentContextAsync(PushSendRequestModel request, bool addIdentifier)
|
||||||
{
|
{
|
||||||
var currentContext = _httpContextAccessor?.HttpContext?.
|
var currentContext = _httpContextAccessor?.HttpContext?.
|
||||||
RequestServices.GetService(typeof(CurrentContext)) as CurrentContext;
|
RequestServices.GetService(typeof(CurrentContext)) as CurrentContext;
|
||||||
if(!string.IsNullOrWhiteSpace(currentContext?.DeviceIdentifier))
|
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();
|
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();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -63,12 +63,14 @@ namespace Bit.Core.Services
|
|||||||
return Task.FromResult(0);
|
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);
|
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);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using SqlServerRepos = Bit.Core.Repositories.SqlServer;
|
using SqlServerRepos = Bit.Core.Repositories.SqlServer;
|
||||||
using PostgreSqlRepos = Bit.Core.Repositories.PostgreSql;
|
using PostgreSqlRepos = Bit.Core.Repositories.PostgreSql;
|
||||||
|
using NoopRepos = Bit.Core.Repositories.Noop;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TableStorageRepos = Bit.Core.Repositories.TableStorage;
|
using TableStorageRepos = Bit.Core.Repositories.TableStorage;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
@ -58,10 +59,12 @@ namespace Bit.Core.Utilities
|
|||||||
if(globalSettings.SelfHosted)
|
if(globalSettings.SelfHosted)
|
||||||
{
|
{
|
||||||
services.AddSingleton<IEventRepository, SqlServerRepos.EventRepository>();
|
services.AddSingleton<IEventRepository, SqlServerRepos.EventRepository>();
|
||||||
|
services.AddSingleton<IInstallationDeviceRepository, NoopRepos.InstallationDeviceRepository>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
services.AddSingleton<IEventRepository, TableStorageRepos.EventRepository>();
|
services.AddSingleton<IEventRepository, TableStorageRepos.EventRepository>();
|
||||||
|
services.AddSingleton<IInstallationDeviceRepository, TableStorageRepos.InstallationDeviceRepository>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user