1
0
mirror of https://github.com/bitwarden/server synced 2025-12-26 05:03:18 +00:00
Files
server/src/Core/Platform/Push/PushServiceCollectionExtensions.cs
Justin Baur e5159a3ba2 [PM-19659] Clean up Notifications code (#6244)
* Move PushType to Platform Folder

- Move the PushType next to the rest of push notification code
- Specifically exclude it from needing Platform code review
- Add tests establishing rules Platform has for usage of this enum, making it safe to have no owner

* Move NotificationHub code into Platform/Push directory

* Update NotificationHub namespace imports

* Add attribute for storing push type metadata

* Rename Push Engines to have PushEngine suffix

* Move Push Registration items to their own directory

* Push code move

* Add expected usage comment

* Add Push feature registration method

- Make method able to be called multipes times with no ill effects

* Add Push Registration service entrypoint and tests

* Use new service entrypoints

* Test changes
2025-08-26 13:30:37 -04:00

83 lines
3.7 KiB
C#

using Azure.Storage.Queues;
using Bit.Core.Platform.Push;
using Bit.Core.Platform.Push.Internal;
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Microsoft.Extensions.DependencyInjection;
/// <summary>
/// Extension methods for adding the Push feature.
/// </summary>
public static class PushServiceCollectionExtensions
{
/// <summary>
/// Adds a <see cref="IPushNotificationService"/> to the services that can be used to send push notifications to
/// end user devices. This method is safe to be ran multiple time provided <see cref="GlobalSettings"/> does not
/// change between calls.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to add services to.</param>
/// <param name="globalSettings">The <see cref="GlobalSettings"/> to use to configure services.</param>
/// <returns>The <see cref="IServiceCollection"/> for additional chaining.</returns>
public static IServiceCollection AddPush(this IServiceCollection services, GlobalSettings globalSettings)
{
ArgumentNullException.ThrowIfNull(services);
ArgumentNullException.ThrowIfNull(globalSettings);
services.TryAddSingleton(TimeProvider.System);
services.TryAddSingleton<IPushNotificationService, MultiServicePushNotificationService>();
if (globalSettings.SelfHosted)
{
if (globalSettings.Installation.Id == Guid.Empty)
{
throw new InvalidOperationException("Installation Id must be set for self-hosted installations.");
}
if (CoreHelpers.SettingHasValue(globalSettings.PushRelayBaseUri) &&
CoreHelpers.SettingHasValue(globalSettings.Installation.Key))
{
// TODO: We should really define the HttpClient we will use here
services.AddHttpClient();
services.AddHttpContextAccessor();
// We also depend on IDeviceRepository but don't explicitly add it right now.
services.TryAddEnumerable(ServiceDescriptor.Singleton<IPushEngine, RelayPushEngine>());
}
if (CoreHelpers.SettingHasValue(globalSettings.InternalIdentityKey) &&
CoreHelpers.SettingHasValue(globalSettings.BaseServiceUri.InternalNotifications))
{
// TODO: We should really define the HttpClient we will use here
services.AddHttpClient();
services.AddHttpContextAccessor();
services.TryAddEnumerable(ServiceDescriptor.Singleton<IPushEngine, NotificationsApiPushEngine>());
}
}
else
{
services.TryAddSingleton<INotificationHubPool, NotificationHubPool>();
services.AddHttpContextAccessor();
// We also depend on IInstallationDeviceRepository but don't explicitly add it right now.
services.TryAddEnumerable(ServiceDescriptor.Singleton<IPushEngine, NotificationHubPushEngine>());
services.TryAddSingleton<IPushRelayer, NotificationHubPushEngine>();
if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
{
services.TryAddKeyedSingleton("notifications", static (sp, _) =>
{
var gs = sp.GetRequiredService<GlobalSettings>();
return new QueueClient(gs.Notifications.ConnectionString, "notifications");
});
// We not IHttpContextAccessor will be added above, no need to do it here.
services.TryAddEnumerable(ServiceDescriptor.Singleton<IPushEngine, AzureQueuePushEngine>());
}
}
return services;
}
}