1
0
mirror of https://github.com/bitwarden/server.git synced 2025-01-01 18:37:35 +01:00

organization status changed code changes (#5113)

* organization status changed code changes

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>

* Add the push notification to subscriptionUpdated

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>

* send notification using the SendPayloadToUser

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>

* Change the implementation to send userId

* Added new implementation for orgstatus sync

* refactor the code and remove private methods

---------

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
This commit is contained in:
cyprain-okeke 2024-12-18 16:31:07 +01:00 committed by GitHub
parent 21fcfcd5e8
commit 322a07477a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 97 additions and 7 deletions

View File

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

View File

@ -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;
}
/// <summary>
@ -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:

View File

@ -25,4 +25,5 @@ public enum PushType : byte
AuthRequestResponse = 16,
SyncOrganizations = 17,
SyncOrganizationStatusChanged = 18,
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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<IPushNotificationService, Task> pushFunc)
{
if (_services != null)

View File

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

View File

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

View File

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

View File

@ -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<PushNotificationData<OrganizationStatusPushNotification>>(
notificationJson, _deserializerOptions);
await hubContext.Clients.Group($"Organization_{orgStatusNotification.Payload.OrganizationId}")
.SendAsync("ReceiveMessage", orgStatusNotification, cancellationToken);
break;
default:
break;
}