From 322a07477a27c759e5b637662cde0a8001ffef80 Mon Sep 17 00:00:00 2001 From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:31:07 +0100 Subject: [PATCH] organization status changed code changes (#5113) * organization status changed code changes Signed-off-by: Cy Okeke * Add the push notification to subscriptionUpdated Signed-off-by: Cy Okeke * send notification using the SendPayloadToUser Signed-off-by: Cy Okeke * Change the implementation to send userId * Added new implementation for orgstatus sync * refactor the code and remove private methods --------- Signed-off-by: Cy Okeke --- .../Implementations/PaymentSucceededHandler.cs | 6 +++++- .../Implementations/SubscriptionUpdatedHandler.cs | 11 ++++++++++- src/Core/Enums/PushType.cs | 1 + src/Core/Models/PushNotification.cs | 6 ++++++ .../NotificationHubPushNotificationService.cs | 12 ++++++++++++ src/Core/Services/IPushNotificationService.cs | 4 +++- .../AzureQueuePushNotificationService.cs | 12 ++++++++++++ .../MultiServicePushNotificationService.cs | 9 ++++++++- .../NotificationsApiPushNotificationService.cs | 14 +++++++++++++- .../RelayPushNotificationService.cs | 14 +++++++++++++- .../NoopPushNotificationService.cs | 8 +++++++- src/Notifications/HubHelpers.cs | 7 +++++++ 12 files changed, 97 insertions(+), 7 deletions(-) diff --git a/src/Billing/Services/Implementations/PaymentSucceededHandler.cs b/src/Billing/Services/Implementations/PaymentSucceededHandler.cs index 6aa8aa2b9..49578187f 100644 --- a/src/Billing/Services/Implementations/PaymentSucceededHandler.cs +++ b/src/Billing/Services/Implementations/PaymentSucceededHandler.cs @@ -25,6 +25,7 @@ public class PaymentSucceededHandler : IPaymentSucceededHandler private readonly ICurrentContext _currentContext; private readonly IUserRepository _userRepository; private readonly IStripeEventUtilityService _stripeEventUtilityService; + private readonly IPushNotificationService _pushNotificationService; public PaymentSucceededHandler( ILogger logger, @@ -37,7 +38,8 @@ public class PaymentSucceededHandler : IPaymentSucceededHandler IUserRepository userRepository, IStripeEventUtilityService stripeEventUtilityService, IUserService userService, - IOrganizationService organizationService) + IOrganizationService organizationService, + IPushNotificationService pushNotificationService) { _logger = logger; _stripeEventService = stripeEventService; @@ -50,6 +52,7 @@ public class PaymentSucceededHandler : IPaymentSucceededHandler _stripeEventUtilityService = stripeEventUtilityService; _userService = userService; _organizationService = organizationService; + _pushNotificationService = pushNotificationService; } /// @@ -140,6 +143,7 @@ public class PaymentSucceededHandler : IPaymentSucceededHandler await _organizationService.EnableAsync(organizationId.Value, subscription.CurrentPeriodEnd); var organization = await _organizationRepository.GetByIdAsync(organizationId.Value); + await _pushNotificationService.PushSyncOrganizationStatusAsync(organization); await _referenceEventService.RaiseEventAsync( new ReferenceEvent(ReferenceEventType.Rebilled, organization, _currentContext) diff --git a/src/Billing/Services/Implementations/SubscriptionUpdatedHandler.cs b/src/Billing/Services/Implementations/SubscriptionUpdatedHandler.cs index 4b4c9dcf4..d49b22b7f 100644 --- a/src/Billing/Services/Implementations/SubscriptionUpdatedHandler.cs +++ b/src/Billing/Services/Implementations/SubscriptionUpdatedHandler.cs @@ -1,5 +1,6 @@ using Bit.Billing.Constants; using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces; +using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Utilities; using Stripe; @@ -15,6 +16,8 @@ public class SubscriptionUpdatedHandler : ISubscriptionUpdatedHandler private readonly IStripeFacade _stripeFacade; private readonly IOrganizationSponsorshipRenewCommand _organizationSponsorshipRenewCommand; private readonly IUserService _userService; + private readonly IPushNotificationService _pushNotificationService; + private readonly IOrganizationRepository _organizationRepository; public SubscriptionUpdatedHandler( IStripeEventService stripeEventService, @@ -22,7 +25,9 @@ public class SubscriptionUpdatedHandler : ISubscriptionUpdatedHandler IOrganizationService organizationService, IStripeFacade stripeFacade, IOrganizationSponsorshipRenewCommand organizationSponsorshipRenewCommand, - IUserService userService) + IUserService userService, + IPushNotificationService pushNotificationService, + IOrganizationRepository organizationRepository) { _stripeEventService = stripeEventService; _stripeEventUtilityService = stripeEventUtilityService; @@ -30,6 +35,8 @@ public class SubscriptionUpdatedHandler : ISubscriptionUpdatedHandler _stripeFacade = stripeFacade; _organizationSponsorshipRenewCommand = organizationSponsorshipRenewCommand; _userService = userService; + _pushNotificationService = pushNotificationService; + _organizationRepository = organizationRepository; } /// @@ -70,6 +77,8 @@ public class SubscriptionUpdatedHandler : ISubscriptionUpdatedHandler case StripeSubscriptionStatus.Active when organizationId.HasValue: { await _organizationService.EnableAsync(organizationId.Value); + var organization = await _organizationRepository.GetByIdAsync(organizationId.Value); + await _pushNotificationService.PushSyncOrganizationStatusAsync(organization); break; } case StripeSubscriptionStatus.Active: diff --git a/src/Core/Enums/PushType.cs b/src/Core/Enums/PushType.cs index 9dbef7b8e..2030b855e 100644 --- a/src/Core/Enums/PushType.cs +++ b/src/Core/Enums/PushType.cs @@ -25,4 +25,5 @@ public enum PushType : byte AuthRequestResponse = 16, SyncOrganizations = 17, + SyncOrganizationStatusChanged = 18, } diff --git a/src/Core/Models/PushNotification.cs b/src/Core/Models/PushNotification.cs index 37b3b25c0..667080580 100644 --- a/src/Core/Models/PushNotification.cs +++ b/src/Core/Models/PushNotification.cs @@ -50,3 +50,9 @@ public class AuthRequestPushNotification public Guid UserId { get; set; } public Guid Id { get; set; } } + +public class OrganizationStatusPushNotification +{ + public Guid OrganizationId { get; set; } + public bool Enabled { get; set; } +} diff --git a/src/Core/NotificationHub/NotificationHubPushNotificationService.cs b/src/Core/NotificationHub/NotificationHubPushNotificationService.cs index 6143676de..7438e812e 100644 --- a/src/Core/NotificationHub/NotificationHubPushNotificationService.cs +++ b/src/Core/NotificationHub/NotificationHubPushNotificationService.cs @@ -1,5 +1,6 @@ using System.Text.Json; using System.Text.RegularExpressions; +using Bit.Core.AdminConsole.Entities; using Bit.Core.Auth.Entities; using Bit.Core.Context; using Bit.Core.Enums; @@ -226,6 +227,17 @@ public class NotificationHubPushNotificationService : IPushNotificationService } } + public async Task PushSyncOrganizationStatusAsync(Organization organization) + { + var message = new OrganizationStatusPushNotification + { + OrganizationId = organization.Id, + Enabled = organization.Enabled + }; + + await SendPayloadToOrganizationAsync(organization.Id, PushType.SyncOrganizationStatusChanged, message, false); + } + private string GetContextIdentifier(bool excludeCurrentContext) { if (!excludeCurrentContext) diff --git a/src/Core/Services/IPushNotificationService.cs b/src/Core/Services/IPushNotificationService.cs index 29a20239d..6e2e47e27 100644 --- a/src/Core/Services/IPushNotificationService.cs +++ b/src/Core/Services/IPushNotificationService.cs @@ -1,4 +1,5 @@ -using Bit.Core.Auth.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.Auth.Entities; using Bit.Core.Enums; using Bit.Core.Tools.Entities; using Bit.Core.Vault.Entities; @@ -27,4 +28,5 @@ public interface IPushNotificationService 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); + Task PushSyncOrganizationStatusAsync(Organization organization); } diff --git a/src/Core/Services/Implementations/AzureQueuePushNotificationService.cs b/src/Core/Services/Implementations/AzureQueuePushNotificationService.cs index 1e4a7314c..3daadebf3 100644 --- a/src/Core/Services/Implementations/AzureQueuePushNotificationService.cs +++ b/src/Core/Services/Implementations/AzureQueuePushNotificationService.cs @@ -1,5 +1,6 @@ using System.Text.Json; using Azure.Storage.Queues; +using Bit.Core.AdminConsole.Entities; using Bit.Core.Auth.Entities; using Bit.Core.Context; using Bit.Core.Enums; @@ -221,4 +222,15 @@ public class AzureQueuePushNotificationService : IPushNotificationService // Noop return Task.FromResult(0); } + + public async Task PushSyncOrganizationStatusAsync(Organization organization) + { + var message = new OrganizationStatusPushNotification + { + OrganizationId = organization.Id, + Enabled = organization.Enabled + }; + await SendMessageAsync(PushType.SyncOrganizationStatusChanged, message, false); + } + } diff --git a/src/Core/Services/Implementations/MultiServicePushNotificationService.cs b/src/Core/Services/Implementations/MultiServicePushNotificationService.cs index 00be72c98..185a11adb 100644 --- a/src/Core/Services/Implementations/MultiServicePushNotificationService.cs +++ b/src/Core/Services/Implementations/MultiServicePushNotificationService.cs @@ -1,4 +1,5 @@ -using Bit.Core.Auth.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.Auth.Entities; using Bit.Core.Enums; using Bit.Core.Settings; using Bit.Core.Tools.Entities; @@ -144,6 +145,12 @@ public class MultiServicePushNotificationService : IPushNotificationService return Task.FromResult(0); } + public Task PushSyncOrganizationStatusAsync(Organization organization) + { + PushToServices((s) => s.PushSyncOrganizationStatusAsync(organization)); + return Task.FromResult(0); + } + private void PushToServices(Func pushFunc) { if (_services != null) diff --git a/src/Core/Services/Implementations/NotificationsApiPushNotificationService.cs b/src/Core/Services/Implementations/NotificationsApiPushNotificationService.cs index 9ec1eb31d..feec75fbe 100644 --- a/src/Core/Services/Implementations/NotificationsApiPushNotificationService.cs +++ b/src/Core/Services/Implementations/NotificationsApiPushNotificationService.cs @@ -1,4 +1,5 @@ -using Bit.Core.Auth.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.Auth.Entities; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Models; @@ -227,4 +228,15 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService // Noop return Task.FromResult(0); } + + public async Task PushSyncOrganizationStatusAsync(Organization organization) + { + var message = new OrganizationStatusPushNotification + { + OrganizationId = organization.Id, + Enabled = organization.Enabled + }; + + await SendMessageAsync(PushType.SyncOrganizationStatusChanged, message, false); + } } diff --git a/src/Core/Services/Implementations/RelayPushNotificationService.cs b/src/Core/Services/Implementations/RelayPushNotificationService.cs index 6cfc0c0a6..d72529677 100644 --- a/src/Core/Services/Implementations/RelayPushNotificationService.cs +++ b/src/Core/Services/Implementations/RelayPushNotificationService.cs @@ -1,4 +1,5 @@ -using Bit.Core.Auth.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.Auth.Entities; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.IdentityServer; @@ -251,4 +252,15 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti { throw new NotImplementedException(); } + + public async Task PushSyncOrganizationStatusAsync(Organization organization) + { + var message = new OrganizationStatusPushNotification + { + OrganizationId = organization.Id, + Enabled = organization.Enabled + }; + + await SendPayloadToOrganizationAsync(organization.Id, PushType.SyncOrganizationStatusChanged, message, false); + } } diff --git a/src/Core/Services/NoopImplementations/NoopPushNotificationService.cs b/src/Core/Services/NoopImplementations/NoopPushNotificationService.cs index d4eff93ef..b5e261622 100644 --- a/src/Core/Services/NoopImplementations/NoopPushNotificationService.cs +++ b/src/Core/Services/NoopImplementations/NoopPushNotificationService.cs @@ -1,4 +1,5 @@ -using Bit.Core.Auth.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.Auth.Entities; using Bit.Core.Enums; using Bit.Core.Tools.Entities; using Bit.Core.Vault.Entities; @@ -88,6 +89,11 @@ public class NoopPushNotificationService : IPushNotificationService return Task.FromResult(0); } + public Task PushSyncOrganizationStatusAsync(Organization organization) + { + return Task.FromResult(0); + } + public Task PushAuthRequestAsync(AuthRequest authRequest) { return Task.FromResult(0); diff --git a/src/Notifications/HubHelpers.cs b/src/Notifications/HubHelpers.cs index 53edb7638..ce2e6b24a 100644 --- a/src/Notifications/HubHelpers.cs +++ b/src/Notifications/HubHelpers.cs @@ -85,6 +85,13 @@ public static class HubHelpers await hubContext.Clients.User(authRequestNotification.Payload.UserId.ToString()) .SendAsync("ReceiveMessage", authRequestNotification, cancellationToken); break; + case PushType.SyncOrganizationStatusChanged: + var orgStatusNotification = + JsonSerializer.Deserialize>( + notificationJson, _deserializerOptions); + await hubContext.Clients.Group($"Organization_{orgStatusNotification.Payload.OrganizationId}") + .SendAsync("ReceiveMessage", orgStatusNotification, cancellationToken); + break; default: break; }