Files
server/src/Core/Services/Implementations/AzureQueuePushNotificationService.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

225 lines
6.6 KiB
C#
Raw Normal View History

using System.Text.Json;
2020-01-10 08:33:13 -05:00
using Azure.Storage.Queues;
[PM-1188] Server owner auth migration (#2825) * [PM-1188] add sso project to auth * [PM-1188] move sso api models to auth * [PM-1188] fix sso api model namespace & imports * [PM-1188] move core files to auth * [PM-1188] fix core sso namespace & models * [PM-1188] move sso repository files to auth * [PM-1188] fix sso repo files namespace & imports * [PM-1188] move sso sql files to auth folder * [PM-1188] move sso test files to auth folders * [PM-1188] fix sso tests namespace & imports * [PM-1188] move auth api files to auth folder * [PM-1188] fix auth api files namespace & imports * [PM-1188] move auth core files to auth folder * [PM-1188] fix auth core files namespace & imports * [PM-1188] move auth email templates to auth folder * [PM-1188] move auth email folder back into shared directory * [PM-1188] fix auth email names * [PM-1188] move auth core models to auth folder * [PM-1188] fix auth model namespace & imports * [PM-1188] add entire Identity project to auth codeowners * [PM-1188] fix auth orm files namespace & imports * [PM-1188] move auth orm files to auth folder * [PM-1188] move auth sql files to auth folder * [PM-1188] move auth tests to auth folder * [PM-1188] fix auth test files namespace & imports * [PM-1188] move emergency access api files to auth folder * [PM-1188] fix emergencyaccess api files namespace & imports * [PM-1188] move emergency access core files to auth folder * [PM-1188] fix emergency access core files namespace & imports * [PM-1188] move emergency access orm files to auth folder * [PM-1188] fix emergency access orm files namespace & imports * [PM-1188] move emergency access sql files to auth folder * [PM-1188] move emergencyaccess test files to auth folder * [PM-1188] fix emergency access test files namespace & imports * [PM-1188] move captcha files to auth folder * [PM-1188] fix captcha files namespace & imports * [PM-1188] move auth admin files into auth folder * [PM-1188] fix admin auth files namespace & imports - configure mvc to look in auth folders for views * [PM-1188] remove extra imports and formatting * [PM-1188] fix ef auth model imports * [PM-1188] fix DatabaseContextModelSnapshot paths * [PM-1188] fix grant import in ef * [PM-1188] update sqlproj * [PM-1188] move missed sqlproj files * [PM-1188] move auth ef models out of auth folder * [PM-1188] fix auth ef models namespace * [PM-1188] remove auth ef models unused imports * [PM-1188] fix imports for auth ef models * [PM-1188] fix more ef model imports * [PM-1188] fix file encodings
2023-04-14 13:25:56 -04:00
using Bit.Core.Auth.Entities;
using Bit.Core.Context;
2018-08-02 17:23:37 -04:00
using Bit.Core.Enums;
using Bit.Core.Models;
using Bit.Core.Settings;
using Bit.Core.Tools.Entities;
using Bit.Core.Utilities;
using Bit.Core.Vault.Entities;
2018-08-02 17:23:37 -04:00
using Microsoft.AspNetCore.Http;
namespace Bit.Core.Services;
2022-08-29 16:06:55 -04:00
2018-08-02 17:23:37 -04:00
public class AzureQueuePushNotificationService : IPushNotificationService
{
2020-01-10 08:33:13 -05:00
private readonly QueueClient _queueClient;
2018-08-02 17:23:37 -04:00
private readonly GlobalSettings _globalSettings;
private readonly IHttpContextAccessor _httpContextAccessor;
public AzureQueuePushNotificationService(
GlobalSettings globalSettings,
IHttpContextAccessor httpContextAccessor)
2018-08-02 17:23:37 -04:00
{
_queueClient = new QueueClient(globalSettings.Notifications.ConnectionString, "notifications");
2018-08-02 17:23:37 -04:00
_globalSettings = globalSettings;
_httpContextAccessor = httpContextAccessor;
2018-08-02 17:23:37 -04:00
}
public async Task PushSyncCipherCreateAsync(Cipher cipher, IEnumerable<Guid> collectionIds)
2018-08-02 17:23:37 -04:00
{
await PushCipherAsync(cipher, PushType.SyncCipherCreate, collectionIds);
2018-08-02 17:23:37 -04:00
}
public async Task PushSyncCipherUpdateAsync(Cipher cipher, IEnumerable<Guid> collectionIds)
{
await PushCipherAsync(cipher, PushType.SyncCipherUpdate, collectionIds);
2018-08-02 17:23:37 -04:00
}
public async Task PushSyncCipherDeleteAsync(Cipher cipher)
{
await PushCipherAsync(cipher, PushType.SyncLoginDelete, null);
}
private async Task PushCipherAsync(Cipher cipher, PushType type, IEnumerable<Guid> collectionIds)
2022-08-29 16:06:55 -04:00
{
if (cipher.OrganizationId.HasValue)
2018-08-02 17:23:37 -04:00
{
var message = new SyncCipherPushNotification
2018-08-02 17:23:37 -04:00
{
Id = cipher.Id,
OrganizationId = cipher.OrganizationId,
RevisionDate = cipher.RevisionDate,
CollectionIds = collectionIds,
};
2018-08-28 08:22:49 -04:00
await SendMessageAsync(type, message, true);
}
2018-08-02 17:23:37 -04:00
else if (cipher.UserId.HasValue)
{
2018-08-02 17:23:37 -04:00
var message = new SyncCipherPushNotification
{
Id = cipher.Id,
UserId = cipher.UserId,
RevisionDate = cipher.RevisionDate,
};
await SendMessageAsync(type, message, true);
}
2022-08-29 16:06:55 -04:00
}
2018-08-02 17:23:37 -04:00
public async Task PushSyncFolderCreateAsync(Folder folder)
{
2018-08-28 08:22:49 -04:00
await PushFolderAsync(folder, PushType.SyncFolderCreate);
2018-08-02 17:23:37 -04:00
}
2018-08-28 08:22:49 -04:00
public async Task PushSyncFolderUpdateAsync(Folder folder)
{
2018-08-28 08:22:49 -04:00
await PushFolderAsync(folder, PushType.SyncFolderUpdate);
}
public async Task PushSyncFolderDeleteAsync(Folder folder)
2022-08-29 14:53:16 -04:00
{
2018-08-28 08:22:49 -04:00
await PushFolderAsync(folder, PushType.SyncFolderDelete);
2018-08-02 17:23:37 -04:00
}
2018-08-28 08:22:49 -04:00
private async Task PushFolderAsync(Folder folder, PushType type)
2022-08-29 16:06:55 -04:00
{
2018-08-28 08:22:49 -04:00
var message = new SyncFolderPushNotification
2022-08-29 14:53:16 -04:00
{
2018-08-02 17:23:37 -04:00
Id = folder.Id,
UserId = folder.UserId,
RevisionDate = folder.RevisionDate
};
await SendMessageAsync(type, message, true);
}
public async Task PushSyncCiphersAsync(Guid userId)
2022-08-29 16:06:55 -04:00
{
await PushUserAsync(userId, PushType.SyncCiphers);
}
public async Task PushSyncVaultAsync(Guid userId)
2022-08-29 16:06:55 -04:00
{
await PushUserAsync(userId, PushType.SyncVault);
}
public async Task PushSyncOrganizationsAsync(Guid userId)
{
await PushUserAsync(userId, PushType.SyncOrganizations);
}
public async Task PushSyncOrgKeysAsync(Guid userId)
{
await PushUserAsync(userId, PushType.SyncOrgKeys);
}
2020-01-10 08:33:13 -05:00
public async Task PushSyncSettingsAsync(Guid userId)
{
2020-01-10 08:33:13 -05:00
await PushUserAsync(userId, PushType.SyncSettings);
2018-08-02 17:23:37 -04:00
}
public async Task PushLogOutAsync(Guid userId, bool excludeCurrentContext = false)
2022-08-29 14:53:16 -04:00
{
await PushUserAsync(userId, PushType.LogOut, excludeCurrentContext);
2022-08-29 14:53:16 -04:00
}
private async Task PushUserAsync(Guid userId, PushType type, bool excludeCurrentContext = false)
2022-08-29 16:06:55 -04:00
{
2018-08-02 17:23:37 -04:00
var message = new UserPushNotification
2022-08-29 14:53:16 -04:00
{
2019-03-19 00:39:03 -04:00
UserId = userId,
2018-08-02 17:23:37 -04:00
Date = DateTime.UtcNow
};
2022-08-29 14:53:16 -04:00
await SendMessageAsync(type, message, excludeCurrentContext);
2022-08-29 14:53:16 -04:00
}
[SG-167] Implement Passwordless Authentication via Notifications (#2276) * [SG-549] Commit Initial AuthRequest Repository (#2174) * Model Passwordless * Scaffold database for Passwordless * Implement SQL Repository * [SG-167] Base Passwordless API (#2185) * Implement Passwordless notifications * Implement Controller * Add documentation to BaseRequestValidator * Register AuthRequestRepo * Remove ExpirationDate from the AuthRequest table * [SG-407] Create job to delete expired requests (#2187) * chore: init * remove exp date * fix: log name * [SG-167] Added fingerprint phrase to response model. (#2233) * Remove FailedLoginAttempt logic * Block unknown devices * Add EF Support for passwordless * Got SignalR working for responses * Added delete job method to EF repo * Implement a GetMany API endpoint for AuthRequests * Ran dotnet format * Fix a merge issues * Redated migration scripts * tried sorting sqlproj * Remove FailedLoginAttempts from SQL * Groom Postgres script * Remove extra commas from migration script * Correct isSpent() * [SG-167] Adde identity validation for passwordless requests. Registered IAuthRepository. * [SG-167] Added origin of the request to response model * Use display name for device identifier in response * Add datetime conversions back to postgres migration script * [SG-655] Add anonymous endpoint for checking if a device & user combo match * [review] Consolidate error conditions Co-authored-by: Brandon Maharaj <107377945+BrandonM-Bitwarden@users.noreply.github.com> Co-authored-by: André Filipe da Silva Bispo <andrefsbispo@hotmail.com> Co-authored-by: André Bispo <abispo@bitwarden.com>
2022-09-26 13:21:13 -04:00
public async Task PushAuthRequestAsync(AuthRequest authRequest)
{
await PushAuthRequestAsync(authRequest, PushType.AuthRequest);
}
public async Task PushAuthRequestResponseAsync(AuthRequest authRequest)
{
await PushAuthRequestAsync(authRequest, PushType.AuthRequestResponse);
}
private async Task PushAuthRequestAsync(AuthRequest authRequest, PushType type)
{
var message = new AuthRequestPushNotification
{
Id = authRequest.Id,
UserId = authRequest.UserId
};
await SendMessageAsync(type, message, true);
}
2018-08-02 17:23:37 -04:00
public async Task PushSyncSendCreateAsync(Send send)
2022-08-29 16:06:55 -04:00
{
2018-08-02 17:23:37 -04:00
await PushSendAsync(send, PushType.SyncSendCreate);
2022-08-29 16:06:55 -04:00
}
2018-08-02 17:23:37 -04:00
public async Task PushSyncSendUpdateAsync(Send send)
2022-08-29 16:06:55 -04:00
{
2018-08-02 17:23:37 -04:00
await PushSendAsync(send, PushType.SyncSendUpdate);
2022-08-29 16:06:55 -04:00
}
2018-08-02 17:23:37 -04:00
public async Task PushSyncSendDeleteAsync(Send send)
2022-08-29 16:06:55 -04:00
{
2018-08-02 17:23:37 -04:00
await PushSendAsync(send, PushType.SyncSendDelete);
2022-08-29 16:06:55 -04:00
}
2018-08-02 17:23:37 -04:00
private async Task PushSendAsync(Send send, PushType type)
2022-08-29 16:06:55 -04:00
{
2018-08-02 17:23:37 -04:00
if (send.UserId.HasValue)
{
var message = new SyncSendPushNotification
2018-08-02 17:23:37 -04:00
{
Id = send.Id,
2019-03-19 00:39:03 -04:00
UserId = send.UserId.Value,
2018-08-02 17:23:37 -04:00
RevisionDate = send.RevisionDate
};
await SendMessageAsync(type, message, true);
2018-08-02 17:23:37 -04:00
}
2022-08-29 16:06:55 -04:00
}
2018-08-02 17:23:37 -04:00
2019-03-19 00:39:03 -04:00
private async Task SendMessageAsync<T>(PushType type, T payload, bool excludeCurrentContext)
2022-08-29 16:06:55 -04:00
{
2019-03-19 00:39:03 -04:00
var contextId = GetContextIdentifier(excludeCurrentContext);
var message = JsonSerializer.Serialize(new PushNotificationData<T>(type, payload, contextId),
JsonHelpers.IgnoreWritingNull);
2018-08-02 21:03:04 -04:00
await _queueClient.SendMessageAsync(message);
2018-08-02 17:23:37 -04:00
}
2022-08-29 14:53:16 -04:00
2019-03-19 00:39:03 -04:00
private string GetContextIdentifier(bool excludeCurrentContext)
2022-08-29 16:06:55 -04:00
{
2019-03-19 00:39:03 -04:00
if (!excludeCurrentContext)
2022-08-29 14:53:16 -04:00
{
2018-08-02 21:03:04 -04:00
return null;
2022-08-29 14:53:16 -04:00
}
2022-08-29 16:06:55 -04:00
var currentContext = _httpContextAccessor?.HttpContext?.
RequestServices.GetService(typeof(ICurrentContext)) as ICurrentContext;
2018-08-02 17:23:37 -04:00
return currentContext?.DeviceIdentifier;
2022-08-29 16:06:55 -04:00
}
2019-03-19 00:39:03 -04:00
public Task SendPayloadToUserAsync(string userId, PushType type, object payload, string identifier,
string deviceId = null)
2022-08-29 16:06:55 -04:00
{
// Noop
2018-08-02 21:03:04 -04:00
return Task.FromResult(0);
2022-08-29 16:06:55 -04:00
}
2019-03-19 00:39:03 -04:00
public Task SendPayloadToOrganizationAsync(string orgId, PushType type, object payload, string identifier,
string deviceId = null)
2022-08-29 16:06:55 -04:00
{
// Noop
2018-08-02 21:03:04 -04:00
return Task.FromResult(0);
2018-08-02 17:23:37 -04:00
}
}