mirror of
https://github.com/bitwarden/server.git
synced 2025-07-04 09:32:48 -05:00
Reference event service implementation (#811)
* Reference event service implementation * Fix IReferenceable implementation of Id * add structure to event body
This commit is contained in:
@ -0,0 +1,49 @@
|
||||
using System.Threading.Tasks;
|
||||
using Azure.Storage.Queues;
|
||||
using Bit.Core.Models.Business;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class AzureQueueReferenceEventService : IReferenceEventService
|
||||
{
|
||||
private const string _queueName = "reference-events";
|
||||
|
||||
private readonly QueueClient _queueClient;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
};
|
||||
|
||||
public AzureQueueReferenceEventService (
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
_queueClient = new QueueClient(globalSettings.Storage.ConnectionString, _queueName);
|
||||
_globalSettings = globalSettings;
|
||||
}
|
||||
|
||||
public async Task RaiseEventAsync(ReferenceEvent referenceEvent)
|
||||
{
|
||||
await SendMessageAsync(referenceEvent);
|
||||
}
|
||||
|
||||
private async Task SendMessageAsync(ReferenceEvent referenceEvent)
|
||||
{
|
||||
if (_globalSettings.SelfHosted || string.IsNullOrWhiteSpace(referenceEvent.ReferenceId))
|
||||
{
|
||||
// Ignore for self-hosted, OR, where there is no ReferenceId
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var message = JsonConvert.SerializeObject(referenceEvent, _jsonSerializerSettings);
|
||||
await _queueClient.SendMessageAsync(message);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore failure
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -34,6 +34,7 @@ namespace Bit.Core.Services
|
||||
private readonly IApplicationCacheService _applicationCacheService;
|
||||
private readonly IPaymentService _paymentService;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
private readonly IReferenceEventService _referenceEventService;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
|
||||
public OrganizationService(
|
||||
@ -53,6 +54,7 @@ namespace Bit.Core.Services
|
||||
IApplicationCacheService applicationCacheService,
|
||||
IPaymentService paymentService,
|
||||
IPolicyRepository policyRepository,
|
||||
IReferenceEventService referenceEventService,
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
_organizationRepository = organizationRepository;
|
||||
@ -71,6 +73,7 @@ namespace Bit.Core.Services
|
||||
_applicationCacheService = applicationCacheService;
|
||||
_paymentService = paymentService;
|
||||
_policyRepository = policyRepository;
|
||||
_referenceEventService = referenceEventService;
|
||||
_globalSettings = globalSettings;
|
||||
}
|
||||
|
||||
@ -108,6 +111,11 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
await _paymentService.CancelSubscriptionAsync(organization, eop);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.CancelSubscription, organization)
|
||||
{
|
||||
EndOfPeriod = endOfPeriod,
|
||||
});
|
||||
}
|
||||
|
||||
public async Task ReinstateSubscriptionAsync(Guid organizationId)
|
||||
@ -119,6 +127,8 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
await _paymentService.ReinstateSubscriptionAsync(organization);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.ReinstateSubscription, organization));
|
||||
}
|
||||
|
||||
public async Task<Tuple<bool, string>> UpgradePlanAsync(Guid organizationId, OrganizationUpgrade upgrade)
|
||||
@ -240,6 +250,17 @@ namespace Bit.Core.Services
|
||||
organization.Plan = newPlan.Name;
|
||||
organization.Enabled = success;
|
||||
await ReplaceAndUpdateCache(organization);
|
||||
if (success)
|
||||
{
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.UpgradePlan, organization)
|
||||
{
|
||||
PlanName = newPlan.Name,
|
||||
PlanType = newPlan.Type,
|
||||
Seats = organization.Seats,
|
||||
Storage = organization.MaxStorageGb,
|
||||
});
|
||||
}
|
||||
|
||||
return new Tuple<bool, string>(success, paymentIntentClientSecret);
|
||||
}
|
||||
@ -265,6 +286,13 @@ namespace Bit.Core.Services
|
||||
|
||||
var secret = await BillingHelpers.AdjustStorageAsync(_paymentService, organization, storageAdjustmentGb,
|
||||
plan.StripeStoragePlanId);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.AdjustStorage, organization)
|
||||
{
|
||||
PlanName = plan.Name,
|
||||
PlanType = plan.Type,
|
||||
Storage = storageAdjustmentGb,
|
||||
});
|
||||
await ReplaceAndUpdateCache(organization);
|
||||
return secret;
|
||||
}
|
||||
@ -399,6 +427,13 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
organization.Seats = (short?)newSeatTotal;
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.AdjustSeats, organization)
|
||||
{
|
||||
PlanName = plan.Name,
|
||||
PlanType = plan.Type,
|
||||
Seats = organization.Seats,
|
||||
});
|
||||
await ReplaceAndUpdateCache(organization);
|
||||
return paymentIntentClientSecret;
|
||||
}
|
||||
@ -503,7 +538,16 @@ namespace Bit.Core.Services
|
||||
signup.PremiumAccessAddon, signup.TaxInfo);
|
||||
}
|
||||
|
||||
return await SignUpAsync(organization, signup.Owner.Id, signup.OwnerKey, signup.CollectionName, true);
|
||||
var returnValue = await SignUpAsync(organization, signup.Owner.Id, signup.OwnerKey, signup.CollectionName, true);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.Signup, organization)
|
||||
{
|
||||
PlanName = plan.Name,
|
||||
PlanType = plan.Type,
|
||||
Seats = returnValue.Item1.Seats,
|
||||
Storage = returnValue.Item1.MaxStorageGb,
|
||||
});
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public async Task<Tuple<Organization, OrganizationUser>> SignUpAsync(
|
||||
@ -741,6 +785,8 @@ namespace Bit.Core.Services
|
||||
var eop = !organization.ExpirationDate.HasValue ||
|
||||
organization.ExpirationDate.Value >= DateTime.UtcNow;
|
||||
await _paymentService.CancelSubscriptionAsync(organization, eop);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.DeleteAccount, organization));
|
||||
}
|
||||
catch (GatewayException) { }
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ namespace Bit.Core.Services
|
||||
private readonly IPaymentService _paymentService;
|
||||
private readonly IPolicyRepository _policyRepository;
|
||||
private readonly IDataProtector _organizationServiceDataProtector;
|
||||
private readonly IReferenceEventService _referenceEventService;
|
||||
private readonly CurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
|
||||
@ -71,6 +72,7 @@ namespace Bit.Core.Services
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
IPaymentService paymentService,
|
||||
IPolicyRepository policyRepository,
|
||||
IReferenceEventService referenceEventService,
|
||||
CurrentContext currentContext,
|
||||
GlobalSettings globalSettings)
|
||||
: base(
|
||||
@ -102,6 +104,7 @@ namespace Bit.Core.Services
|
||||
_policyRepository = policyRepository;
|
||||
_organizationServiceDataProtector = dataProtectionProvider.CreateProtector(
|
||||
"OrganizationServiceDataProtector");
|
||||
_referenceEventService = referenceEventService;
|
||||
_currentContext = currentContext;
|
||||
_globalSettings = globalSettings;
|
||||
}
|
||||
@ -219,6 +222,8 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
await _userRepository.DeleteAsync(user);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.DeleteAccount, user));
|
||||
await _pushService.PushLogOutAsync(user.Id);
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
@ -288,6 +293,8 @@ namespace Bit.Core.Services
|
||||
if (result == IdentityResult.Success)
|
||||
{
|
||||
await _mailService.SendWelcomeEmailAsync(user);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.Signup, user));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -765,6 +772,12 @@ namespace Bit.Core.Services
|
||||
{
|
||||
await SaveUserAsync(user);
|
||||
await _pushService.PushSyncVaultAsync(user.Id);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.UpgradePlan, user)
|
||||
{
|
||||
Storage = user.MaxStorageGb,
|
||||
PlanName = PremiumPlanId,
|
||||
});
|
||||
}
|
||||
catch when(!_globalSettings.SelfHosted)
|
||||
{
|
||||
@ -841,6 +854,12 @@ namespace Bit.Core.Services
|
||||
|
||||
var secret = await BillingHelpers.AdjustStorageAsync(_paymentService, user, storageAdjustmentGb,
|
||||
StoragePlanId);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.AdjustStorage, user)
|
||||
{
|
||||
Storage = storageAdjustmentGb,
|
||||
PlanName = StoragePlanId,
|
||||
});
|
||||
await SaveUserAsync(user);
|
||||
return secret;
|
||||
}
|
||||
@ -868,11 +887,18 @@ namespace Bit.Core.Services
|
||||
eop = false;
|
||||
}
|
||||
await _paymentService.CancelSubscriptionAsync(user, eop, accountDelete);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.CancelSubscription, user)
|
||||
{
|
||||
EndOfPeriod = eop,
|
||||
});
|
||||
}
|
||||
|
||||
public async Task ReinstatePremiumAsync(User user)
|
||||
{
|
||||
await _paymentService.ReinstateSubscriptionAsync(user);
|
||||
await _referenceEventService.RaiseEventAsync(
|
||||
new ReferenceEvent(ReferenceEventType.ReinstateSubscription, user));
|
||||
}
|
||||
|
||||
public async Task EnablePremiumAsync(Guid userId, DateTime? expirationDate)
|
||||
|
Reference in New Issue
Block a user