1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-02 09:10:33 -05:00

Remove gathering and reporting of ReferenceEvents

This commit is contained in:
Daniel James Smith 2025-05-29 12:58:44 +02:00
parent 829ce86066
commit ea308f51df
No known key found for this signature in database
GPG Key ID: DA2E2EC600E1289B
47 changed files with 15 additions and 1149 deletions

View File

@ -12,7 +12,6 @@ using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Extensions; using Bit.Core.Billing.Extensions;
using Bit.Core.Billing.Pricing; using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Providers.Services; using Bit.Core.Billing.Providers.Services;
using Bit.Core.Context;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models.OrganizationConnectionConfigs; using Bit.Core.Models.OrganizationConnectionConfigs;
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces; using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
@ -20,9 +19,6 @@ using Bit.Core.Repositories;
using Bit.Core.SecretsManager.Repositories; using Bit.Core.SecretsManager.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Core.Vault.Repositories; using Bit.Core.Vault.Repositories;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
@ -45,12 +41,9 @@ public class OrganizationsController : Controller
private readonly IPaymentService _paymentService; private readonly IPaymentService _paymentService;
private readonly IApplicationCacheService _applicationCacheService; private readonly IApplicationCacheService _applicationCacheService;
private readonly GlobalSettings _globalSettings; private readonly GlobalSettings _globalSettings;
private readonly IReferenceEventService _referenceEventService;
private readonly IUserService _userService;
private readonly IProviderRepository _providerRepository; private readonly IProviderRepository _providerRepository;
private readonly ILogger<OrganizationsController> _logger; private readonly ILogger<OrganizationsController> _logger;
private readonly IAccessControlService _accessControlService; private readonly IAccessControlService _accessControlService;
private readonly ICurrentContext _currentContext;
private readonly ISecretRepository _secretRepository; private readonly ISecretRepository _secretRepository;
private readonly IProjectRepository _projectRepository; private readonly IProjectRepository _projectRepository;
private readonly IServiceAccountRepository _serviceAccountRepository; private readonly IServiceAccountRepository _serviceAccountRepository;
@ -73,12 +66,9 @@ public class OrganizationsController : Controller
IPaymentService paymentService, IPaymentService paymentService,
IApplicationCacheService applicationCacheService, IApplicationCacheService applicationCacheService,
GlobalSettings globalSettings, GlobalSettings globalSettings,
IReferenceEventService referenceEventService,
IUserService userService,
IProviderRepository providerRepository, IProviderRepository providerRepository,
ILogger<OrganizationsController> logger, ILogger<OrganizationsController> logger,
IAccessControlService accessControlService, IAccessControlService accessControlService,
ICurrentContext currentContext,
ISecretRepository secretRepository, ISecretRepository secretRepository,
IProjectRepository projectRepository, IProjectRepository projectRepository,
IServiceAccountRepository serviceAccountRepository, IServiceAccountRepository serviceAccountRepository,
@ -100,12 +90,9 @@ public class OrganizationsController : Controller
_paymentService = paymentService; _paymentService = paymentService;
_applicationCacheService = applicationCacheService; _applicationCacheService = applicationCacheService;
_globalSettings = globalSettings; _globalSettings = globalSettings;
_referenceEventService = referenceEventService;
_userService = userService;
_providerRepository = providerRepository; _providerRepository = providerRepository;
_logger = logger; _logger = logger;
_accessControlService = accessControlService; _accessControlService = accessControlService;
_currentContext = currentContext;
_secretRepository = secretRepository; _secretRepository = secretRepository;
_projectRepository = projectRepository; _projectRepository = projectRepository;
_serviceAccountRepository = serviceAccountRepository; _serviceAccountRepository = serviceAccountRepository;
@ -272,11 +259,6 @@ public class OrganizationsController : Controller
await _organizationRepository.ReplaceAsync(organization); await _organizationRepository.ReplaceAsync(organization);
await _applicationCacheService.UpsertOrganizationAbilityAsync(organization); await _applicationCacheService.UpsertOrganizationAbilityAsync(organization);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.OrganizationEditedByAdmin, organization, _currentContext)
{
EventRaisedByUser = _userService.GetUserName(User),
SalesAssistedTrialStarted = model.SalesAssistedTrialStarted,
});
return RedirectToAction("Edit", new { id }); return RedirectToAction("Edit", new { id });
} }

View File

@ -6,14 +6,10 @@ using Bit.Api.Utilities;
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces; using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
using Bit.Core.Billing.Models; using Bit.Core.Billing.Models;
using Bit.Core.Billing.Services; using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Business; using Bit.Core.Models.Business;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -161,8 +157,6 @@ public class AccountsController(
[HttpPost("cancel")] [HttpPost("cancel")]
public async Task PostCancelAsync( public async Task PostCancelAsync(
[FromBody] SubscriptionCancellationRequestModel request, [FromBody] SubscriptionCancellationRequestModel request,
[FromServices] ICurrentContext currentContext,
[FromServices] IReferenceEventService referenceEventService,
[FromServices] ISubscriberService subscriberService) [FromServices] ISubscriberService subscriberService)
{ {
var user = await userService.GetUserByPrincipalAsync(User); var user = await userService.GetUserByPrincipalAsync(User);
@ -175,12 +169,6 @@ public class AccountsController(
await subscriberService.CancelSubscription(user, await subscriberService.CancelSubscription(user,
new OffboardingSurveyResponse { UserId = user.Id, Reason = request.Reason, Feedback = request.Feedback }, new OffboardingSurveyResponse { UserId = user.Id, Reason = request.Reason, Feedback = request.Feedback },
user.IsExpired()); user.IsExpired());
await referenceEventService.RaiseEventAsync(new ReferenceEvent(
ReferenceEventType.CancelSubscription,
user,
currentContext)
{ EndOfPeriod = user.IsExpired() });
} }
[HttpPost("reinstate-premium")] [HttpPost("reinstate-premium")]

View File

@ -20,9 +20,6 @@ using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -44,7 +41,6 @@ public class OrganizationsController(
IUpdateSecretsManagerSubscriptionCommand updateSecretsManagerSubscriptionCommand, IUpdateSecretsManagerSubscriptionCommand updateSecretsManagerSubscriptionCommand,
IUpgradeOrganizationPlanCommand upgradeOrganizationPlanCommand, IUpgradeOrganizationPlanCommand upgradeOrganizationPlanCommand,
IAddSecretsManagerSubscriptionCommand addSecretsManagerSubscriptionCommand, IAddSecretsManagerSubscriptionCommand addSecretsManagerSubscriptionCommand,
IReferenceEventService referenceEventService,
ISubscriberService subscriberService, ISubscriberService subscriberService,
IOrganizationInstallationRepository organizationInstallationRepository, IOrganizationInstallationRepository organizationInstallationRepository,
IPricingClient pricingClient) IPricingClient pricingClient)
@ -246,14 +242,6 @@ public class OrganizationsController(
Feedback = request.Feedback Feedback = request.Feedback
}, },
organization.IsExpired()); organization.IsExpired());
await referenceEventService.RaiseEventAsync(new ReferenceEvent(
ReferenceEventType.CancelSubscription,
organization,
currentContext)
{
EndOfPeriod = organization.IsExpired()
});
} }
[HttpPost("{id:guid}/reinstate")] [HttpPost("{id:guid}/reinstate")]

View File

@ -5,7 +5,6 @@ using Bit.Core.Context;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Identity; using Bit.Core.Identity;
using Bit.Core.Repositories;
using Bit.Core.SecretsManager.AuthorizationRequirements; using Bit.Core.SecretsManager.AuthorizationRequirements;
using Bit.Core.SecretsManager.Commands.Secrets.Interfaces; using Bit.Core.SecretsManager.Commands.Secrets.Interfaces;
using Bit.Core.SecretsManager.Entities; using Bit.Core.SecretsManager.Entities;
@ -16,9 +15,6 @@ using Bit.Core.SecretsManager.Queries.Interfaces;
using Bit.Core.SecretsManager.Queries.Secrets.Interfaces; using Bit.Core.SecretsManager.Queries.Secrets.Interfaces;
using Bit.Core.SecretsManager.Repositories; using Bit.Core.SecretsManager.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -30,7 +26,6 @@ public class SecretsController : Controller
private readonly ICurrentContext _currentContext; private readonly ICurrentContext _currentContext;
private readonly IProjectRepository _projectRepository; private readonly IProjectRepository _projectRepository;
private readonly ISecretRepository _secretRepository; private readonly ISecretRepository _secretRepository;
private readonly IOrganizationRepository _organizationRepository;
private readonly ICreateSecretCommand _createSecretCommand; private readonly ICreateSecretCommand _createSecretCommand;
private readonly IUpdateSecretCommand _updateSecretCommand; private readonly IUpdateSecretCommand _updateSecretCommand;
private readonly IDeleteSecretCommand _deleteSecretCommand; private readonly IDeleteSecretCommand _deleteSecretCommand;
@ -39,14 +34,12 @@ public class SecretsController : Controller
private readonly ISecretAccessPoliciesUpdatesQuery _secretAccessPoliciesUpdatesQuery; private readonly ISecretAccessPoliciesUpdatesQuery _secretAccessPoliciesUpdatesQuery;
private readonly IUserService _userService; private readonly IUserService _userService;
private readonly IEventService _eventService; private readonly IEventService _eventService;
private readonly IReferenceEventService _referenceEventService;
private readonly IAuthorizationService _authorizationService; private readonly IAuthorizationService _authorizationService;
public SecretsController( public SecretsController(
ICurrentContext currentContext, ICurrentContext currentContext,
IProjectRepository projectRepository, IProjectRepository projectRepository,
ISecretRepository secretRepository, ISecretRepository secretRepository,
IOrganizationRepository organizationRepository,
ICreateSecretCommand createSecretCommand, ICreateSecretCommand createSecretCommand,
IUpdateSecretCommand updateSecretCommand, IUpdateSecretCommand updateSecretCommand,
IDeleteSecretCommand deleteSecretCommand, IDeleteSecretCommand deleteSecretCommand,
@ -55,13 +48,11 @@ public class SecretsController : Controller
ISecretAccessPoliciesUpdatesQuery secretAccessPoliciesUpdatesQuery, ISecretAccessPoliciesUpdatesQuery secretAccessPoliciesUpdatesQuery,
IUserService userService, IUserService userService,
IEventService eventService, IEventService eventService,
IReferenceEventService referenceEventService,
IAuthorizationService authorizationService) IAuthorizationService authorizationService)
{ {
_currentContext = currentContext; _currentContext = currentContext;
_projectRepository = projectRepository; _projectRepository = projectRepository;
_secretRepository = secretRepository; _secretRepository = secretRepository;
_organizationRepository = organizationRepository;
_createSecretCommand = createSecretCommand; _createSecretCommand = createSecretCommand;
_updateSecretCommand = updateSecretCommand; _updateSecretCommand = updateSecretCommand;
_deleteSecretCommand = deleteSecretCommand; _deleteSecretCommand = deleteSecretCommand;
@ -70,7 +61,6 @@ public class SecretsController : Controller
_secretAccessPoliciesUpdatesQuery = secretAccessPoliciesUpdatesQuery; _secretAccessPoliciesUpdatesQuery = secretAccessPoliciesUpdatesQuery;
_userService = userService; _userService = userService;
_eventService = eventService; _eventService = eventService;
_referenceEventService = referenceEventService;
_authorizationService = authorizationService; _authorizationService = authorizationService;
} }
@ -148,9 +138,6 @@ public class SecretsController : Controller
if (_currentContext.IdentityClientType == IdentityClientType.ServiceAccount) if (_currentContext.IdentityClientType == IdentityClientType.ServiceAccount)
{ {
await _eventService.LogServiceAccountSecretEventAsync(userId, secret, EventType.Secret_Retrieved); await _eventService.LogServiceAccountSecretEventAsync(userId, secret, EventType.Secret_Retrieved);
var org = await _organizationRepository.GetByIdAsync(secret.OrganizationId);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.SmServiceAccountAccessedSecret, org, _currentContext));
} }
return new SecretResponseModel(secret, access.Read, access.Write); return new SecretResponseModel(secret, access.Read, access.Write);
@ -266,7 +253,7 @@ public class SecretsController : Controller
throw new NotFoundException(); throw new NotFoundException();
} }
await LogSecretsRetrievalAsync(secrets.First().OrganizationId, secrets); await LogSecretsRetrievalAsync(secrets);
var responses = secrets.Select(s => new BaseSecretResponseModel(s)); var responses = secrets.Select(s => new BaseSecretResponseModel(s));
return new ListResponseModel<BaseSecretResponseModel>(responses); return new ListResponseModel<BaseSecretResponseModel>(responses);
@ -303,21 +290,18 @@ public class SecretsController : Controller
if (syncResult.HasChanges) if (syncResult.HasChanges)
{ {
await LogSecretsRetrievalAsync(organizationId, syncResult.Secrets); await LogSecretsRetrievalAsync(syncResult.Secrets);
} }
return new SecretsSyncResponseModel(syncResult.HasChanges, syncResult.Secrets); return new SecretsSyncResponseModel(syncResult.HasChanges, syncResult.Secrets);
} }
private async Task LogSecretsRetrievalAsync(Guid organizationId, IEnumerable<Secret> secrets) private async Task LogSecretsRetrievalAsync(IEnumerable<Secret> secrets)
{ {
if (_currentContext.IdentityClientType == IdentityClientType.ServiceAccount) if (_currentContext.IdentityClientType == IdentityClientType.ServiceAccount)
{ {
var userId = _userService.GetProperUserId(User)!.Value; var userId = _userService.GetProperUserId(User)!.Value;
var org = await _organizationRepository.GetByIdAsync(organizationId);
await _eventService.LogServiceAccountSecretsEventAsync(userId, secrets, EventType.Secret_Retrieved); await _eventService.LogServiceAccountSecretsEventAsync(userId, secrets, EventType.Secret_Retrieved);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.SmServiceAccountAccessedSecret, org, _currentContext));
} }
} }
} }

View File

@ -5,7 +5,6 @@ using Bit.Api.Tools.Models.Request;
using Bit.Api.Tools.Models.Response; using Bit.Api.Tools.Models.Response;
using Bit.Api.Utilities; using Bit.Api.Utilities;
using Bit.Core; using Bit.Core;
using Bit.Core.Context;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
@ -33,7 +32,6 @@ public class SendsController : Controller
private readonly INonAnonymousSendCommand _nonAnonymousSendCommand; private readonly INonAnonymousSendCommand _nonAnonymousSendCommand;
private readonly ILogger<SendsController> _logger; private readonly ILogger<SendsController> _logger;
private readonly GlobalSettings _globalSettings; private readonly GlobalSettings _globalSettings;
private readonly ICurrentContext _currentContext;
public SendsController( public SendsController(
ISendRepository sendRepository, ISendRepository sendRepository,
@ -43,8 +41,7 @@ public class SendsController : Controller
INonAnonymousSendCommand nonAnonymousSendCommand, INonAnonymousSendCommand nonAnonymousSendCommand,
ISendFileStorageService sendFileStorageService, ISendFileStorageService sendFileStorageService,
ILogger<SendsController> logger, ILogger<SendsController> logger,
GlobalSettings globalSettings, GlobalSettings globalSettings)
ICurrentContext currentContext)
{ {
_sendRepository = sendRepository; _sendRepository = sendRepository;
_userService = userService; _userService = userService;
@ -54,7 +51,6 @@ public class SendsController : Controller
_sendFileStorageService = sendFileStorageService; _sendFileStorageService = sendFileStorageService;
_logger = logger; _logger = logger;
_globalSettings = globalSettings; _globalSettings = globalSettings;
_currentContext = currentContext;
} }
#region Anonymous endpoints #region Anonymous endpoints

View File

@ -1,8 +1,4 @@
using Bit.Core.Context; using Bit.Core.Repositories;
using Bit.Core.Repositories;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Event = Stripe.Event; using Event = Stripe.Event;
namespace Bit.Billing.Services.Implementations; namespace Bit.Billing.Services.Implementations;
@ -10,23 +6,17 @@ namespace Bit.Billing.Services.Implementations;
public class CustomerUpdatedHandler : ICustomerUpdatedHandler public class CustomerUpdatedHandler : ICustomerUpdatedHandler
{ {
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext;
private readonly IStripeEventService _stripeEventService; private readonly IStripeEventService _stripeEventService;
private readonly IStripeEventUtilityService _stripeEventUtilityService; private readonly IStripeEventUtilityService _stripeEventUtilityService;
private readonly ILogger<CustomerUpdatedHandler> _logger; private readonly ILogger<CustomerUpdatedHandler> _logger;
public CustomerUpdatedHandler( public CustomerUpdatedHandler(
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IReferenceEventService referenceEventService,
ICurrentContext currentContext,
IStripeEventService stripeEventService, IStripeEventService stripeEventService,
IStripeEventUtilityService stripeEventUtilityService, IStripeEventUtilityService stripeEventUtilityService,
ILogger<CustomerUpdatedHandler> logger) ILogger<CustomerUpdatedHandler> logger)
{ {
_organizationRepository = organizationRepository ?? throw new ArgumentNullException(nameof(organizationRepository)); _organizationRepository = organizationRepository ?? throw new ArgumentNullException(nameof(organizationRepository));
_referenceEventService = referenceEventService;
_currentContext = currentContext;
_stripeEventService = stripeEventService; _stripeEventService = stripeEventService;
_stripeEventUtilityService = stripeEventUtilityService; _stripeEventUtilityService = stripeEventUtilityService;
_logger = logger; _logger = logger;
@ -95,20 +85,5 @@ public class CustomerUpdatedHandler : ICustomerUpdatedHandler
organization.BillingEmail = customer.Email; organization.BillingEmail = customer.Email;
await _organizationRepository.ReplaceAsync(organization); await _organizationRepository.ReplaceAsync(organization);
if (_referenceEventService == null)
{
_logger.LogError("ReferenceEventService was not initialized in CustomerUpdatedHandler");
throw new InvalidOperationException($"{nameof(_referenceEventService)} is not initialized");
}
if (_currentContext == null)
{
_logger.LogError("CurrentContext was not initialized in CustomerUpdatedHandler");
throw new InvalidOperationException($"{nameof(_currentContext)} is not initialized");
}
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.OrganizationEditedInStripe, organization, _currentContext));
} }
} }

View File

@ -3,13 +3,9 @@ using Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Interfaces;
using Bit.Core.AdminConsole.Repositories; using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Billing.Enums; using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Pricing; using Bit.Core.Billing.Pricing;
using Bit.Core.Context;
using Bit.Core.Platform.Push; using Bit.Core.Platform.Push;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Event = Stripe.Event; using Event = Stripe.Event;
namespace Bit.Billing.Services.Implementations; namespace Bit.Billing.Services.Implementations;
@ -22,9 +18,6 @@ public class PaymentSucceededHandler : IPaymentSucceededHandler
private readonly IStripeFacade _stripeFacade; private readonly IStripeFacade _stripeFacade;
private readonly IProviderRepository _providerRepository; private readonly IProviderRepository _providerRepository;
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext;
private readonly IUserRepository _userRepository;
private readonly IStripeEventUtilityService _stripeEventUtilityService; private readonly IStripeEventUtilityService _stripeEventUtilityService;
private readonly IPushNotificationService _pushNotificationService; private readonly IPushNotificationService _pushNotificationService;
private readonly IOrganizationEnableCommand _organizationEnableCommand; private readonly IOrganizationEnableCommand _organizationEnableCommand;
@ -36,9 +29,6 @@ public class PaymentSucceededHandler : IPaymentSucceededHandler
IStripeFacade stripeFacade, IStripeFacade stripeFacade,
IProviderRepository providerRepository, IProviderRepository providerRepository,
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IReferenceEventService referenceEventService,
ICurrentContext currentContext,
IUserRepository userRepository,
IStripeEventUtilityService stripeEventUtilityService, IStripeEventUtilityService stripeEventUtilityService,
IUserService userService, IUserService userService,
IPushNotificationService pushNotificationService, IPushNotificationService pushNotificationService,
@ -50,9 +40,6 @@ public class PaymentSucceededHandler : IPaymentSucceededHandler
_stripeFacade = stripeFacade; _stripeFacade = stripeFacade;
_providerRepository = providerRepository; _providerRepository = providerRepository;
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_referenceEventService = referenceEventService;
_currentContext = currentContext;
_userRepository = userRepository;
_stripeEventUtilityService = stripeEventUtilityService; _stripeEventUtilityService = stripeEventUtilityService;
_userService = userService; _userService = userService;
_pushNotificationService = pushNotificationService; _pushNotificationService = pushNotificationService;
@ -116,27 +103,7 @@ public class PaymentSucceededHandler : IPaymentSucceededHandler
_logger.LogError("invoice.payment_succeeded webhook ({EventID}) for Provider ({ProviderID}) indicates missing subscription line items", _logger.LogError("invoice.payment_succeeded webhook ({EventID}) for Provider ({ProviderID}) indicates missing subscription line items",
parsedEvent.Id, parsedEvent.Id,
provider.Id); provider.Id);
return;
} }
await _referenceEventService.RaiseEventAsync(new ReferenceEvent
{
Type = ReferenceEventType.Rebilled,
Source = ReferenceEventSource.Provider,
Id = provider.Id,
PlanType = PlanType.TeamsMonthly,
Seats = (int)teamsMonthlyLineItem.Quantity
});
await _referenceEventService.RaiseEventAsync(new ReferenceEvent
{
Type = ReferenceEventType.Rebilled,
Source = ReferenceEventSource.Provider,
Id = provider.Id,
PlanType = PlanType.EnterpriseMonthly,
Seats = (int)enterpriseMonthlyLineItem.Quantity
});
} }
else if (organizationId.HasValue) else if (organizationId.HasValue)
{ {
@ -156,15 +123,6 @@ public class PaymentSucceededHandler : IPaymentSucceededHandler
await _organizationEnableCommand.EnableAsync(organizationId.Value, subscription.CurrentPeriodEnd); await _organizationEnableCommand.EnableAsync(organizationId.Value, subscription.CurrentPeriodEnd);
await _pushNotificationService.PushSyncOrganizationStatusAsync(organization); await _pushNotificationService.PushSyncOrganizationStatusAsync(organization);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.Rebilled, organization, _currentContext)
{
PlanName = organization?.Plan,
PlanType = organization?.PlanType,
Seats = organization?.Seats,
Storage = organization?.MaxStorageGb,
});
} }
else if (userId.HasValue) else if (userId.HasValue)
{ {
@ -174,14 +132,6 @@ public class PaymentSucceededHandler : IPaymentSucceededHandler
} }
await _userService.EnablePremiumAsync(userId.Value, subscription.CurrentPeriodEnd); await _userService.EnablePremiumAsync(userId.Value, subscription.CurrentPeriodEnd);
var user = await _userRepository.GetByIdAsync(userId.Value);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.Rebilled, user, _currentContext)
{
PlanName = IStripeEventUtilityService.PremiumPlanId,
Storage = user?.MaxStorageGb,
});
} }
} }
} }

View File

@ -8,14 +8,13 @@ using Bit.Core.Entities;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models.Business; using Bit.Core.Models.Business;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Entities;
using Bit.Core.Utilities; using Bit.Core.Utilities;
#nullable enable #nullable enable
namespace Bit.Core.AdminConsole.Entities; namespace Bit.Core.AdminConsole.Entities;
public class Organization : ITableObject<Guid>, IStorableSubscriber, IRevisable, IReferenceable public class Organization : ITableObject<Guid>, IStorableSubscriber, IRevisable
{ {
private Dictionary<TwoFactorProviderType, TwoFactorProvider>? _twoFactorProviders; private Dictionary<TwoFactorProviderType, TwoFactorProvider>? _twoFactorProviders;

View File

@ -1,15 +1,11 @@
using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces; using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Interfaces;
using Bit.Core.AdminConsole.Repositories; using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Context;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Data; using Bit.Core.Models.Data;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Groups; namespace Bit.Core.AdminConsole.OrganizationFeatures.Groups;
@ -18,21 +14,16 @@ public class CreateGroupCommand : ICreateGroupCommand
private readonly IEventService _eventService; private readonly IEventService _eventService;
private readonly IGroupRepository _groupRepository; private readonly IGroupRepository _groupRepository;
private readonly IOrganizationUserRepository _organizationUserRepository; private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext;
public CreateGroupCommand( public CreateGroupCommand(
IEventService eventService, IEventService eventService,
IGroupRepository groupRepository, IGroupRepository groupRepository,
IOrganizationUserRepository organizationUserRepository, IOrganizationUserRepository organizationUserRepository
IReferenceEventService referenceEventService, )
ICurrentContext currentContext)
{ {
_eventService = eventService; _eventService = eventService;
_groupRepository = groupRepository; _groupRepository = groupRepository;
_organizationUserRepository = organizationUserRepository; _organizationUserRepository = organizationUserRepository;
_referenceEventService = referenceEventService;
_currentContext = currentContext;
} }
public async Task CreateGroupAsync(Group group, Organization organization, public async Task CreateGroupAsync(Group group, Organization organization,
@ -77,8 +68,6 @@ public class CreateGroupCommand : ICreateGroupCommand
{ {
await _groupRepository.CreateAsync(group, collections); await _groupRepository.CreateAsync(group, collections);
} }
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.GroupCreated, organization, _currentContext));
} }
private async Task GroupRepositoryUpdateUsersAsync(Group group, IEnumerable<Guid> userIds, private async Task GroupRepositoryUpdateUsersAsync(Group group, IEnumerable<Guid> userIds,

View File

@ -7,9 +7,6 @@ using Bit.Core.Exceptions;
using Bit.Core.Platform.Push; using Bit.Core.Platform.Push;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
#nullable enable #nullable enable
@ -24,7 +21,6 @@ public class DeleteClaimedOrganizationUserAccountCommand : IDeleteClaimedOrganiz
private readonly IUserRepository _userRepository; private readonly IUserRepository _userRepository;
private readonly ICurrentContext _currentContext; private readonly ICurrentContext _currentContext;
private readonly IHasConfirmedOwnersExceptQuery _hasConfirmedOwnersExceptQuery; private readonly IHasConfirmedOwnersExceptQuery _hasConfirmedOwnersExceptQuery;
private readonly IReferenceEventService _referenceEventService;
private readonly IPushNotificationService _pushService; private readonly IPushNotificationService _pushService;
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IProviderUserRepository _providerUserRepository; private readonly IProviderUserRepository _providerUserRepository;
@ -36,7 +32,6 @@ public class DeleteClaimedOrganizationUserAccountCommand : IDeleteClaimedOrganiz
IUserRepository userRepository, IUserRepository userRepository,
ICurrentContext currentContext, ICurrentContext currentContext,
IHasConfirmedOwnersExceptQuery hasConfirmedOwnersExceptQuery, IHasConfirmedOwnersExceptQuery hasConfirmedOwnersExceptQuery,
IReferenceEventService referenceEventService,
IPushNotificationService pushService, IPushNotificationService pushService,
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IProviderUserRepository providerUserRepository) IProviderUserRepository providerUserRepository)
@ -48,7 +43,6 @@ public class DeleteClaimedOrganizationUserAccountCommand : IDeleteClaimedOrganiz
_userRepository = userRepository; _userRepository = userRepository;
_currentContext = currentContext; _currentContext = currentContext;
_hasConfirmedOwnersExceptQuery = hasConfirmedOwnersExceptQuery; _hasConfirmedOwnersExceptQuery = hasConfirmedOwnersExceptQuery;
_referenceEventService = referenceEventService;
_pushService = pushService; _pushService = pushService;
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_providerUserRepository = providerUserRepository; _providerUserRepository = providerUserRepository;
@ -195,8 +189,6 @@ public class DeleteClaimedOrganizationUserAccountCommand : IDeleteClaimedOrganiz
await _userRepository.DeleteManyAsync(users); await _userRepository.DeleteManyAsync(users);
foreach (var user in users) foreach (var user in users)
{ {
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.DeleteAccount, user, _currentContext));
await _pushService.PushLogOutAsync(user.Id); await _pushService.PushLogOutAsync(user.Id);
} }

View File

@ -9,15 +9,11 @@ using Bit.Core.AdminConsole.Repositories;
using Bit.Core.AdminConsole.Utilities.Commands; using Bit.Core.AdminConsole.Utilities.Commands;
using Bit.Core.AdminConsole.Utilities.Errors; using Bit.Core.AdminConsole.Utilities.Errors;
using Bit.Core.AdminConsole.Utilities.Validation; using Bit.Core.AdminConsole.Utilities.Validation;
using Bit.Core.Context;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models.Business; using Bit.Core.Models.Business;
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface; using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using OrganizationUserInvite = Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models.OrganizationUserInvite; using OrganizationUserInvite = Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models.OrganizationUserInvite;
@ -28,8 +24,6 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
IInviteUsersValidator inviteUsersValidator, IInviteUsersValidator inviteUsersValidator,
IPaymentService paymentService, IPaymentService paymentService,
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IReferenceEventService referenceEventService,
ICurrentContext currentContext,
IApplicationCacheService applicationCacheService, IApplicationCacheService applicationCacheService,
IMailService mailService, IMailService mailService,
ILogger<InviteOrganizationUsersCommand> logger, ILogger<InviteOrganizationUsersCommand> logger,
@ -121,8 +115,6 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
await SendAdditionalEmailsAsync(validatedRequest, organization); await SendAdditionalEmailsAsync(validatedRequest, organization);
await SendInvitesAsync(organizationUserToInviteEntities, organization); await SendInvitesAsync(organizationUserToInviteEntities, organization);
await PublishReferenceEventAsync(validatedRequest, organization);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -190,14 +182,6 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
} }
} }
private async Task PublishReferenceEventAsync(Valid<InviteOrganizationUsersValidationRequest> validatedResult,
Organization organization) =>
await referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.InvitedUsers, organization, currentContext)
{
Users = validatedResult.Value.Invites.Length
});
private async Task SendInvitesAsync(IEnumerable<CreateOrganizationUser> users, Organization organization) => private async Task SendInvitesAsync(IEnumerable<CreateOrganizationUser> users, Organization organization) =>
await sendOrganizationInvitesCommand.SendInvitesAsync( await sendOrganizationInvitesCommand.SendInvitesAsync(
new SendInvitesRequest( new SendInvitesRequest(
@ -284,15 +268,6 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
await organizationRepository.ReplaceAsync(organization); // could optimize this with only a property update await organizationRepository.ReplaceAsync(organization); // could optimize this with only a property update
await applicationCacheService.UpsertOrganizationAbilityAsync(organization); await applicationCacheService.UpsertOrganizationAbilityAsync(organization);
await referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.AdjustSeats, organization, currentContext)
{
PlanName = validatedResult.Value.InviteOrganization.Plan.Name,
PlanType = validatedResult.Value.InviteOrganization.Plan.Type,
Seats = validatedResult.Value.PasswordManagerSubscriptionUpdate.UpdatedSeatTotal,
PreviousSeats = validatedResult.Value.PasswordManagerSubscriptionUpdate.Seats
});
} }
} }
} }

View File

@ -5,7 +5,6 @@ using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Models.Sales; using Bit.Core.Billing.Models.Sales;
using Bit.Core.Billing.Pricing; using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services; using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
@ -15,9 +14,6 @@ using Bit.Core.Models.StaticStore;
using Bit.Core.Platform.Push; using Bit.Core.Platform.Push;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations; namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations;
@ -36,8 +32,6 @@ public class CloudOrganizationSignUpCommand(
IOrganizationBillingService organizationBillingService, IOrganizationBillingService organizationBillingService,
IPaymentService paymentService, IPaymentService paymentService,
IPolicyService policyService, IPolicyService policyService,
IReferenceEventService referenceEventService,
ICurrentContext currentContext,
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IOrganizationApiKeyRepository organizationApiKeyRepository, IOrganizationApiKeyRepository organizationApiKeyRepository,
IApplicationCacheService applicationCacheService, IApplicationCacheService applicationCacheService,
@ -132,17 +126,6 @@ public class CloudOrganizationSignUpCommand(
var ownerId = signup.IsFromProvider ? default : signup.Owner.Id; var ownerId = signup.IsFromProvider ? default : signup.Owner.Id;
var returnValue = await SignUpAsync(organization, ownerId, signup.OwnerKey, signup.CollectionName, true); var returnValue = await SignUpAsync(organization, ownerId, signup.OwnerKey, signup.CollectionName, true);
await referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.Signup, organization, currentContext)
{
PlanName = plan.Name,
PlanType = plan.Type,
Seats = returnValue.Item1.Seats,
SignupInitiationPath = signup.InitiationPath,
Storage = returnValue.Item1.MaxStorageGb,
// TODO: add reference events for SmSeats and Service Accounts - see AC-1481
});
return new SignUpOrganizationResponse(returnValue.organization, returnValue.organizationUser); return new SignUpOrganizationResponse(returnValue.organization, returnValue.organizationUser);
} }

View File

@ -2,38 +2,28 @@
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Interfaces; using Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Interfaces;
using Bit.Core.Auth.Enums; using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Repositories; using Bit.Core.Auth.Repositories;
using Bit.Core.Context;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations; namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations;
public class OrganizationDeleteCommand : IOrganizationDeleteCommand public class OrganizationDeleteCommand : IOrganizationDeleteCommand
{ {
private readonly IApplicationCacheService _applicationCacheService; private readonly IApplicationCacheService _applicationCacheService;
private readonly ICurrentContext _currentContext;
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IPaymentService _paymentService; private readonly IPaymentService _paymentService;
private readonly IReferenceEventService _referenceEventService;
private readonly ISsoConfigRepository _ssoConfigRepository; private readonly ISsoConfigRepository _ssoConfigRepository;
public OrganizationDeleteCommand( public OrganizationDeleteCommand(
IApplicationCacheService applicationCacheService, IApplicationCacheService applicationCacheService,
ICurrentContext currentContext,
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IPaymentService paymentService, IPaymentService paymentService,
IReferenceEventService referenceEventService,
ISsoConfigRepository ssoConfigRepository) ISsoConfigRepository ssoConfigRepository)
{ {
_applicationCacheService = applicationCacheService; _applicationCacheService = applicationCacheService;
_currentContext = currentContext;
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_paymentService = paymentService; _paymentService = paymentService;
_referenceEventService = referenceEventService;
_ssoConfigRepository = ssoConfigRepository; _ssoConfigRepository = ssoConfigRepository;
} }
@ -48,8 +38,6 @@ public class OrganizationDeleteCommand : IOrganizationDeleteCommand
var eop = !organization.ExpirationDate.HasValue || var eop = !organization.ExpirationDate.HasValue ||
organization.ExpirationDate.Value >= DateTime.UtcNow; organization.ExpirationDate.Value >= DateTime.UtcNow;
await _paymentService.CancelSubscriptionAsync(organization, eop); await _paymentService.CancelSubscriptionAsync(organization, eop);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.DeleteAccount, organization, _currentContext));
} }
catch (GatewayException) { } catch (GatewayException) { }
} }

View File

@ -8,9 +8,6 @@ using Bit.Core.Models.Business;
using Bit.Core.Models.StaticStore; using Bit.Core.Models.StaticStore;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations; namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations;
@ -37,7 +34,6 @@ public class ProviderClientOrganizationSignUpCommand : IProviderClientOrganizati
private readonly ICurrentContext _currentContext; private readonly ICurrentContext _currentContext;
private readonly IPricingClient _pricingClient; private readonly IPricingClient _pricingClient;
private readonly IReferenceEventService _referenceEventService;
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationApiKeyRepository _organizationApiKeyRepository; private readonly IOrganizationApiKeyRepository _organizationApiKeyRepository;
private readonly IApplicationCacheService _applicationCacheService; private readonly IApplicationCacheService _applicationCacheService;
@ -46,7 +42,6 @@ public class ProviderClientOrganizationSignUpCommand : IProviderClientOrganizati
public ProviderClientOrganizationSignUpCommand( public ProviderClientOrganizationSignUpCommand(
ICurrentContext currentContext, ICurrentContext currentContext,
IPricingClient pricingClient, IPricingClient pricingClient,
IReferenceEventService referenceEventService,
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IOrganizationApiKeyRepository organizationApiKeyRepository, IOrganizationApiKeyRepository organizationApiKeyRepository,
IApplicationCacheService applicationCacheService, IApplicationCacheService applicationCacheService,
@ -54,7 +49,6 @@ public class ProviderClientOrganizationSignUpCommand : IProviderClientOrganizati
{ {
_currentContext = currentContext; _currentContext = currentContext;
_pricingClient = pricingClient; _pricingClient = pricingClient;
_referenceEventService = referenceEventService;
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_organizationApiKeyRepository = organizationApiKeyRepository; _organizationApiKeyRepository = organizationApiKeyRepository;
_applicationCacheService = applicationCacheService; _applicationCacheService = applicationCacheService;
@ -108,16 +102,6 @@ public class ProviderClientOrganizationSignUpCommand : IProviderClientOrganizati
var returnValue = await SignUpAsync(organization, signup.CollectionName); var returnValue = await SignUpAsync(organization, signup.CollectionName);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.Signup, organization, _currentContext)
{
PlanName = plan.Name,
PlanType = plan.Type,
Seats = returnValue.Organization.Seats,
SignupInitiationPath = signup.InitiationPath,
Storage = returnValue.Organization.MaxStorageGb,
});
return returnValue; return returnValue;
} }

View File

@ -29,9 +29,6 @@ using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
using Bit.Core.Platform.Push; using Bit.Core.Platform.Push;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Stripe; using Stripe;
@ -56,7 +53,6 @@ public class OrganizationService : IOrganizationService
private readonly IPolicyRepository _policyRepository; private readonly IPolicyRepository _policyRepository;
private readonly IPolicyService _policyService; private readonly IPolicyService _policyService;
private readonly ISsoUserRepository _ssoUserRepository; private readonly ISsoUserRepository _ssoUserRepository;
private readonly IReferenceEventService _referenceEventService;
private readonly IGlobalSettings _globalSettings; private readonly IGlobalSettings _globalSettings;
private readonly IOrganizationApiKeyRepository _organizationApiKeyRepository; private readonly IOrganizationApiKeyRepository _organizationApiKeyRepository;
private readonly ICurrentContext _currentContext; private readonly ICurrentContext _currentContext;
@ -88,7 +84,6 @@ public class OrganizationService : IOrganizationService
IPolicyRepository policyRepository, IPolicyRepository policyRepository,
IPolicyService policyService, IPolicyService policyService,
ISsoUserRepository ssoUserRepository, ISsoUserRepository ssoUserRepository,
IReferenceEventService referenceEventService,
IGlobalSettings globalSettings, IGlobalSettings globalSettings,
IOrganizationApiKeyRepository organizationApiKeyRepository, IOrganizationApiKeyRepository organizationApiKeyRepository,
ICurrentContext currentContext, ICurrentContext currentContext,
@ -120,7 +115,6 @@ public class OrganizationService : IOrganizationService
_policyRepository = policyRepository; _policyRepository = policyRepository;
_policyService = policyService; _policyService = policyService;
_ssoUserRepository = ssoUserRepository; _ssoUserRepository = ssoUserRepository;
_referenceEventService = referenceEventService;
_globalSettings = globalSettings; _globalSettings = globalSettings;
_organizationApiKeyRepository = organizationApiKeyRepository; _organizationApiKeyRepository = organizationApiKeyRepository;
_currentContext = currentContext; _currentContext = currentContext;
@ -153,11 +147,6 @@ public class OrganizationService : IOrganizationService
} }
await _paymentService.CancelSubscriptionAsync(organization, eop); await _paymentService.CancelSubscriptionAsync(organization, eop);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.CancelSubscription, organization, _currentContext)
{
EndOfPeriod = endOfPeriod,
});
} }
public async Task ReinstateSubscriptionAsync(Guid organizationId) public async Task ReinstateSubscriptionAsync(Guid organizationId)
@ -169,8 +158,6 @@ public class OrganizationService : IOrganizationService
} }
await _paymentService.ReinstateSubscriptionAsync(organization); await _paymentService.ReinstateSubscriptionAsync(organization);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.ReinstateSubscription, organization, _currentContext));
} }
public async Task<string> AdjustStorageAsync(Guid organizationId, short storageAdjustmentGb) public async Task<string> AdjustStorageAsync(Guid organizationId, short storageAdjustmentGb)
@ -190,13 +177,6 @@ public class OrganizationService : IOrganizationService
var secret = await BillingHelpers.AdjustStorageAsync(_paymentService, organization, storageAdjustmentGb, var secret = await BillingHelpers.AdjustStorageAsync(_paymentService, organization, storageAdjustmentGb,
plan.PasswordManager.StripeStoragePlanId); plan.PasswordManager.StripeStoragePlanId);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.AdjustStorage, organization, _currentContext)
{
PlanName = plan.Name,
PlanType = plan.Type,
Storage = storageAdjustmentGb,
});
await ReplaceAndUpdateCacheAsync(organization); await ReplaceAndUpdateCacheAsync(organization);
return secret; return secret;
} }
@ -328,14 +308,6 @@ public class OrganizationService : IOrganizationService
} }
var paymentIntentClientSecret = await _paymentService.AdjustSeatsAsync(organization, plan, additionalSeats); var paymentIntentClientSecret = await _paymentService.AdjustSeatsAsync(organization, plan, additionalSeats);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.AdjustSeats, organization, _currentContext)
{
PlanName = plan.Name,
PlanType = plan.Type,
Seats = newSeatTotal,
PreviousSeats = organization.Seats
});
organization.Seats = (short?)newSeatTotal; organization.Seats = (short?)newSeatTotal;
await ReplaceAndUpdateCacheAsync(organization); await ReplaceAndUpdateCacheAsync(organization);
@ -886,12 +858,6 @@ public class OrganizationService : IOrganizationService
} }
await SendInvitesAsync(allOrgUsers, organization); await SendInvitesAsync(allOrgUsers, organization);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.InvitedUsers, organization, _currentContext)
{
Users = orgUserInvitedCount
});
} }
catch (Exception e) catch (Exception e)
{ {
@ -1317,8 +1283,6 @@ public class OrganizationService : IOrganizationService
} }
await _eventService.LogOrganizationUserEventsAsync(events.Select(e => (e.ou, e.e, eventSystemUser, e.d))); await _eventService.LogOrganizationUserEventsAsync(events.Select(e => (e.ou, e.e, eventSystemUser, e.d)));
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.DirectorySynced, organization, _currentContext));
} }
public async Task DeleteSsoUserAsync(Guid userId, Guid? organizationId) public async Task DeleteSsoUserAsync(Guid userId, Guid? organizationId)
@ -1754,11 +1718,5 @@ public class OrganizationService : IOrganizationService
await SendInviteAsync(ownerOrganizationUser, organization, true); await SendInviteAsync(ownerOrganizationUser, organization, true);
await _eventService.LogOrganizationUserEventAsync(ownerOrganizationUser, EventType.OrganizationUser_Invited); await _eventService.LogOrganizationUserEventAsync(ownerOrganizationUser, EventType.OrganizationUser_Invited);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.OrganizationCreatedByAdmin, organization, _currentContext)
{
EventRaisedByUser = userService.GetUserName(user),
SalesAssistedTrialStarted = salesAssistedTrialStarted,
});
} }
} }

View File

@ -3,7 +3,6 @@ using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Auth.Enums; using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Models; using Bit.Core.Auth.Models;
using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Context;
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces; using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
@ -11,9 +10,6 @@ using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tokens; using Bit.Core.Tokens;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
@ -26,15 +22,12 @@ public class RegisterUserCommand : IRegisterUserCommand
private readonly IGlobalSettings _globalSettings; private readonly IGlobalSettings _globalSettings;
private readonly IOrganizationUserRepository _organizationUserRepository; private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IPolicyRepository _policyRepository; private readonly IPolicyRepository _policyRepository;
private readonly IReferenceEventService _referenceEventService;
private readonly IDataProtectorTokenFactory<OrgUserInviteTokenable> _orgUserInviteTokenDataFactory; private readonly IDataProtectorTokenFactory<OrgUserInviteTokenable> _orgUserInviteTokenDataFactory;
private readonly IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> _registrationEmailVerificationTokenDataFactory; private readonly IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> _registrationEmailVerificationTokenDataFactory;
private readonly IDataProtector _organizationServiceDataProtector; private readonly IDataProtector _organizationServiceDataProtector;
private readonly IDataProtector _providerServiceDataProtector; private readonly IDataProtector _providerServiceDataProtector;
private readonly ICurrentContext _currentContext;
private readonly IUserService _userService; private readonly IUserService _userService;
private readonly IMailService _mailService; private readonly IMailService _mailService;
@ -48,11 +41,9 @@ public class RegisterUserCommand : IRegisterUserCommand
IGlobalSettings globalSettings, IGlobalSettings globalSettings,
IOrganizationUserRepository organizationUserRepository, IOrganizationUserRepository organizationUserRepository,
IPolicyRepository policyRepository, IPolicyRepository policyRepository,
IReferenceEventService referenceEventService,
IDataProtectionProvider dataProtectionProvider, IDataProtectionProvider dataProtectionProvider,
IDataProtectorTokenFactory<OrgUserInviteTokenable> orgUserInviteTokenDataFactory, IDataProtectorTokenFactory<OrgUserInviteTokenable> orgUserInviteTokenDataFactory,
IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> registrationEmailVerificationTokenDataFactory, IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> registrationEmailVerificationTokenDataFactory,
ICurrentContext currentContext,
IUserService userService, IUserService userService,
IMailService mailService, IMailService mailService,
IValidateRedemptionTokenCommand validateRedemptionTokenCommand, IValidateRedemptionTokenCommand validateRedemptionTokenCommand,
@ -62,14 +53,12 @@ public class RegisterUserCommand : IRegisterUserCommand
_globalSettings = globalSettings; _globalSettings = globalSettings;
_organizationUserRepository = organizationUserRepository; _organizationUserRepository = organizationUserRepository;
_policyRepository = policyRepository; _policyRepository = policyRepository;
_referenceEventService = referenceEventService;
_organizationServiceDataProtector = dataProtectionProvider.CreateProtector( _organizationServiceDataProtector = dataProtectionProvider.CreateProtector(
"OrganizationServiceDataProtector"); "OrganizationServiceDataProtector");
_orgUserInviteTokenDataFactory = orgUserInviteTokenDataFactory; _orgUserInviteTokenDataFactory = orgUserInviteTokenDataFactory;
_registrationEmailVerificationTokenDataFactory = registrationEmailVerificationTokenDataFactory; _registrationEmailVerificationTokenDataFactory = registrationEmailVerificationTokenDataFactory;
_currentContext = currentContext;
_userService = userService; _userService = userService;
_mailService = mailService; _mailService = mailService;
@ -86,7 +75,6 @@ public class RegisterUserCommand : IRegisterUserCommand
if (result == IdentityResult.Success) if (result == IdentityResult.Success)
{ {
await _mailService.SendWelcomeEmailAsync(user); await _mailService.SendWelcomeEmailAsync(user);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user, _currentContext));
} }
return result; return result;
@ -119,12 +107,6 @@ public class RegisterUserCommand : IRegisterUserCommand
sentWelcomeEmail = true; sentWelcomeEmail = true;
if (!string.IsNullOrEmpty(initiationPath)) if (!string.IsNullOrEmpty(initiationPath))
{ {
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.Signup, user, _currentContext)
{
SignupInitiationPath = initiationPath
});
return result; return result;
} }
} }
@ -134,8 +116,6 @@ public class RegisterUserCommand : IRegisterUserCommand
{ {
await _mailService.SendWelcomeEmailAsync(user); await _mailService.SendWelcomeEmailAsync(user);
} }
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user, _currentContext));
} }
return result; return result;
@ -263,10 +243,6 @@ public class RegisterUserCommand : IRegisterUserCommand
if (result == IdentityResult.Success) if (result == IdentityResult.Success)
{ {
await _mailService.SendWelcomeEmailAsync(user); await _mailService.SendWelcomeEmailAsync(user);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user, _currentContext)
{
ReceiveMarketingEmails = tokenable.ReceiveMarketingEmails
});
} }
return result; return result;
@ -285,7 +261,6 @@ public class RegisterUserCommand : IRegisterUserCommand
if (result == IdentityResult.Success) if (result == IdentityResult.Success)
{ {
await _mailService.SendWelcomeEmailAsync(user); await _mailService.SendWelcomeEmailAsync(user);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user, _currentContext));
} }
return result; return result;
@ -306,7 +281,6 @@ public class RegisterUserCommand : IRegisterUserCommand
if (result == IdentityResult.Success) if (result == IdentityResult.Success)
{ {
await _mailService.SendWelcomeEmailAsync(user); await _mailService.SendWelcomeEmailAsync(user);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user, _currentContext));
} }
return result; return result;
@ -325,7 +299,6 @@ public class RegisterUserCommand : IRegisterUserCommand
if (result == IdentityResult.Success) if (result == IdentityResult.Success)
{ {
await _mailService.SendWelcomeEmailAsync(user); await _mailService.SendWelcomeEmailAsync(user);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user, _currentContext));
} }
return result; return result;

View File

@ -3,7 +3,6 @@ using System.Text.Json;
using Bit.Core.Auth.Enums; using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Models; using Bit.Core.Auth.Models;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Tools.Entities;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
@ -11,7 +10,7 @@ using Microsoft.AspNetCore.Identity;
namespace Bit.Core.Entities; namespace Bit.Core.Entities;
public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFactorProvidersUser, IReferenceable public class User : ITableObject<Guid>, IStorableSubscriber, IRevisable, ITwoFactorProvidersUser
{ {
private Dictionary<TwoFactorProviderType, TwoFactorProvider>? _twoFactorProviders; private Dictionary<TwoFactorProviderType, TwoFactorProvider>? _twoFactorProviders;

View File

@ -8,7 +8,6 @@ using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Models.Sales; using Bit.Core.Billing.Models.Sales;
using Bit.Core.Billing.Pricing; using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services; using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Business; using Bit.Core.Models.Business;
@ -16,9 +15,6 @@ using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.SecretsManager.Repositories; using Bit.Core.SecretsManager.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
namespace Bit.Core.OrganizationFeatures.OrganizationSubscriptions; namespace Bit.Core.OrganizationFeatures.OrganizationSubscriptions;
@ -30,9 +26,7 @@ public class UpgradeOrganizationPlanCommand : IUpgradeOrganizationPlanCommand
private readonly IPaymentService _paymentService; private readonly IPaymentService _paymentService;
private readonly IPolicyRepository _policyRepository; private readonly IPolicyRepository _policyRepository;
private readonly ISsoConfigRepository _ssoConfigRepository; private readonly ISsoConfigRepository _ssoConfigRepository;
private readonly IReferenceEventService _referenceEventService;
private readonly IOrganizationConnectionRepository _organizationConnectionRepository; private readonly IOrganizationConnectionRepository _organizationConnectionRepository;
private readonly ICurrentContext _currentContext;
private readonly IServiceAccountRepository _serviceAccountRepository; private readonly IServiceAccountRepository _serviceAccountRepository;
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationService _organizationService; private readonly IOrganizationService _organizationService;
@ -47,9 +41,7 @@ public class UpgradeOrganizationPlanCommand : IUpgradeOrganizationPlanCommand
IPaymentService paymentService, IPaymentService paymentService,
IPolicyRepository policyRepository, IPolicyRepository policyRepository,
ISsoConfigRepository ssoConfigRepository, ISsoConfigRepository ssoConfigRepository,
IReferenceEventService referenceEventService,
IOrganizationConnectionRepository organizationConnectionRepository, IOrganizationConnectionRepository organizationConnectionRepository,
ICurrentContext currentContext,
IServiceAccountRepository serviceAccountRepository, IServiceAccountRepository serviceAccountRepository,
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IOrganizationService organizationService, IOrganizationService organizationService,
@ -63,9 +55,7 @@ public class UpgradeOrganizationPlanCommand : IUpgradeOrganizationPlanCommand
_paymentService = paymentService; _paymentService = paymentService;
_policyRepository = policyRepository; _policyRepository = policyRepository;
_ssoConfigRepository = ssoConfigRepository; _ssoConfigRepository = ssoConfigRepository;
_referenceEventService = referenceEventService;
_organizationConnectionRepository = organizationConnectionRepository; _organizationConnectionRepository = organizationConnectionRepository;
_currentContext = currentContext;
_serviceAccountRepository = serviceAccountRepository; _serviceAccountRepository = serviceAccountRepository;
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_organizationService = organizationService; _organizationService = organizationService;
@ -285,25 +275,6 @@ public class UpgradeOrganizationPlanCommand : IUpgradeOrganizationPlanCommand
} }
await _organizationService.ReplaceAndUpdateCacheAsync(organization); await _organizationService.ReplaceAndUpdateCacheAsync(organization);
if (success)
{
var upgradePath = GetUpgradePath(existingPlan.ProductTier, newPlan.ProductTier);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.UpgradePlan, organization, _currentContext)
{
PlanName = newPlan.Name,
PlanType = newPlan.Type,
OldPlanName = existingPlan.Name,
OldPlanType = existingPlan.Type,
Seats = organization.Seats,
SignupInitiationPath = "Upgrade in-product",
PlanUpgradePath = upgradePath,
Storage = organization.MaxStorageGb,
// TODO: add reference events for SmSeats and Service Accounts - see AC-1481
});
}
return new Tuple<bool, string>(success, paymentIntentClientSecret); return new Tuple<bool, string>(success, paymentIntentClientSecret);
} }

View File

@ -1,13 +1,9 @@
#nullable enable #nullable enable
using Bit.Core.Context;
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Data; using Bit.Core.Models.Data;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
namespace Bit.Core.Services; namespace Bit.Core.Services;
@ -17,23 +13,17 @@ public class CollectionService : ICollectionService
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationUserRepository _organizationUserRepository; private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly ICollectionRepository _collectionRepository; private readonly ICollectionRepository _collectionRepository;
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext;
public CollectionService( public CollectionService(
IEventService eventService, IEventService eventService,
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository, IOrganizationUserRepository organizationUserRepository,
ICollectionRepository collectionRepository, ICollectionRepository collectionRepository)
IReferenceEventService referenceEventService,
ICurrentContext currentContext)
{ {
_eventService = eventService; _eventService = eventService;
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_organizationUserRepository = organizationUserRepository; _organizationUserRepository = organizationUserRepository;
_collectionRepository = collectionRepository; _collectionRepository = collectionRepository;
_referenceEventService = referenceEventService;
_currentContext = currentContext;
} }
public async Task SaveAsync(Collection collection, IEnumerable<CollectionAccessSelection>? groups = null, public async Task SaveAsync(Collection collection, IEnumerable<CollectionAccessSelection>? groups = null,
@ -78,7 +68,6 @@ public class CollectionService : ICollectionService
await _collectionRepository.CreateAsync(collection, org.UseGroups ? groupsList : null, usersList); await _collectionRepository.CreateAsync(collection, org.UseGroups ? groupsList : null, usersList);
await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Created); await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Created);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.CollectionCreated, org, _currentContext));
} }
else else
{ {

View File

@ -30,9 +30,6 @@ using Bit.Core.Platform.Push;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tokens; using Bit.Core.Tokens;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Core.Vault.Repositories; using Bit.Core.Vault.Repositories;
using Fido2NetLib; using Fido2NetLib;
@ -69,7 +66,6 @@ public class UserService : UserManager<User>, IUserService, IDisposable
private readonly IPolicyRepository _policyRepository; private readonly IPolicyRepository _policyRepository;
private readonly IPolicyService _policyService; private readonly IPolicyService _policyService;
private readonly IDataProtector _organizationServiceDataProtector; private readonly IDataProtector _organizationServiceDataProtector;
private readonly IReferenceEventService _referenceEventService;
private readonly IFido2 _fido2; private readonly IFido2 _fido2;
private readonly ICurrentContext _currentContext; private readonly ICurrentContext _currentContext;
private readonly IGlobalSettings _globalSettings; private readonly IGlobalSettings _globalSettings;
@ -109,7 +105,6 @@ public class UserService : UserManager<User>, IUserService, IDisposable
IPaymentService paymentService, IPaymentService paymentService,
IPolicyRepository policyRepository, IPolicyRepository policyRepository,
IPolicyService policyService, IPolicyService policyService,
IReferenceEventService referenceEventService,
IFido2 fido2, IFido2 fido2,
ICurrentContext currentContext, ICurrentContext currentContext,
IGlobalSettings globalSettings, IGlobalSettings globalSettings,
@ -154,7 +149,6 @@ public class UserService : UserManager<User>, IUserService, IDisposable
_policyService = policyService; _policyService = policyService;
_organizationServiceDataProtector = dataProtectionProvider.CreateProtector( _organizationServiceDataProtector = dataProtectionProvider.CreateProtector(
"OrganizationServiceDataProtector"); "OrganizationServiceDataProtector");
_referenceEventService = referenceEventService;
_fido2 = fido2; _fido2 = fido2;
_currentContext = currentContext; _currentContext = currentContext;
_globalSettings = globalSettings; _globalSettings = globalSettings;
@ -299,8 +293,6 @@ public class UserService : UserManager<User>, IUserService, IDisposable
} }
await _userRepository.DeleteAsync(user); await _userRepository.DeleteAsync(user);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.DeleteAccount, user, _currentContext));
await _pushService.PushLogOutAsync(user.Id); await _pushService.PushLogOutAsync(user.Id);
return IdentityResult.Success; return IdentityResult.Success;
} }
@ -1046,12 +1038,6 @@ public class UserService : UserManager<User>, IUserService, IDisposable
{ {
await SaveUserAsync(user); await SaveUserAsync(user);
await _pushService.PushSyncVaultAsync(user.Id); await _pushService.PushSyncVaultAsync(user.Id);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.UpgradePlan, user, _currentContext)
{
Storage = user.MaxStorageGb,
PlanName = PremiumPlanId,
});
} }
catch when (!_globalSettings.SelfHosted) catch when (!_globalSettings.SelfHosted)
{ {
@ -1117,12 +1103,6 @@ public class UserService : UserManager<User>, IUserService, IDisposable
var secret = await BillingHelpers.AdjustStorageAsync(_paymentService, user, storageAdjustmentGb, var secret = await BillingHelpers.AdjustStorageAsync(_paymentService, user, storageAdjustmentGb,
StripeConstants.Prices.StoragePlanPersonal); StripeConstants.Prices.StoragePlanPersonal);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.AdjustStorage, user, _currentContext)
{
Storage = storageAdjustmentGb,
PlanName = StripeConstants.Prices.StoragePlanPersonal,
});
await SaveUserAsync(user); await SaveUserAsync(user);
return secret; return secret;
} }
@ -1150,18 +1130,11 @@ public class UserService : UserManager<User>, IUserService, IDisposable
eop = false; eop = false;
} }
await _paymentService.CancelSubscriptionAsync(user, eop); await _paymentService.CancelSubscriptionAsync(user, eop);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.CancelSubscription, user, _currentContext)
{
EndOfPeriod = eop
});
} }
public async Task ReinstatePremiumAsync(User user) public async Task ReinstatePremiumAsync(User user)
{ {
await _paymentService.ReinstateSubscriptionAsync(user); await _paymentService.ReinstateSubscriptionAsync(user);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.ReinstateSubscription, user, _currentContext));
} }
public async Task EnablePremiumAsync(Guid userId, DateTime? expirationDate) public async Task EnablePremiumAsync(Guid userId, DateTime? expirationDate)
@ -1446,17 +1419,6 @@ public class UserService : UserManager<User>, IUserService, IDisposable
await Task.WhenAll(legacyRevokeOrgUserTasks); await Task.WhenAll(legacyRevokeOrgUserTasks);
} }
public override async Task<IdentityResult> ConfirmEmailAsync(User user, string token)
{
var result = await base.ConfirmEmailAsync(user, token);
if (result.Succeeded)
{
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.ConfirmEmailAddress, user, _currentContext));
}
return result;
}
public async Task RotateApiKeyAsync(User user) public async Task RotateApiKeyAsync(User user)
{ {
user.ApiKey = CoreHelpers.SecureRandomString(30); user.ApiKey = CoreHelpers.SecureRandomString(30);

View File

@ -1,29 +0,0 @@
#nullable enable
using Bit.Core.Tools.Models.Business;
namespace Bit.Core.Tools.Entities;
/// <summary>
/// An entity that can be referenced by a <see cref="ReferenceEvent"/>.
/// </summary>
public interface IReferenceable
{
/// <summary>
/// Identifies the entity that generated the event.
/// </summary>
Guid Id { get; set; }
/// <summary>
/// Contextual information included in the event.
/// </summary>
/// <remarks>
/// Do not store secrets in this field.
/// </remarks>
string? ReferenceData { get; set; }
/// <summary>
/// Returns <see langword="true" /> when the entity is a user.
/// Otherwise returns <see langword="false" />.
/// </summary>
bool IsUser();
}

View File

@ -1,15 +0,0 @@
using System.Runtime.Serialization;
namespace Bit.Core.Tools.Enums;
public enum ReferenceEventSource
{
[EnumMember(Value = "organization")]
Organization,
[EnumMember(Value = "user")]
User,
[EnumMember(Value = "provider")]
Provider,
[EnumMember(Value = "registration")]
Registration,
}

View File

@ -1,53 +0,0 @@
using System.Runtime.Serialization;
namespace Bit.Core.Tools.Enums;
public enum ReferenceEventType
{
[EnumMember(Value = "signup-email-submit")]
SignupEmailSubmit,
[EnumMember(Value = "signup-email-clicked")]
SignupEmailClicked,
[EnumMember(Value = "signup")]
Signup,
[EnumMember(Value = "upgrade-plan")]
UpgradePlan,
[EnumMember(Value = "adjust-storage")]
AdjustStorage,
[EnumMember(Value = "adjust-seats")]
AdjustSeats,
[EnumMember(Value = "cancel-subscription")]
CancelSubscription,
[EnumMember(Value = "reinstate-subscription")]
ReinstateSubscription,
[EnumMember(Value = "delete-account")]
DeleteAccount,
[EnumMember(Value = "confirm-email")]
ConfirmEmailAddress,
[EnumMember(Value = "invited-users")]
InvitedUsers,
[EnumMember(Value = "rebilled")]
Rebilled,
[EnumMember(Value = "send-created")]
SendCreated,
[EnumMember(Value = "send-accessed")]
SendAccessed,
[EnumMember(Value = "directory-synced")]
DirectorySynced,
[EnumMember(Value = "vault-imported")]
VaultImported,
[EnumMember(Value = "cipher-created")]
CipherCreated,
[EnumMember(Value = "group-created")]
GroupCreated,
[EnumMember(Value = "collection-created")]
CollectionCreated,
[EnumMember(Value = "organization-edited-by-admin")]
OrganizationEditedByAdmin,
[EnumMember(Value = "organization-created-by-admin")]
OrganizationCreatedByAdmin,
[EnumMember(Value = "organization-edited-in-stripe")]
OrganizationEditedInStripe,
[EnumMember(Value = "sm-service-account-accessed-secret")]
SmServiceAccountAccessedSecret,
}

View File

@ -2,16 +2,12 @@
using Bit.Core.AdminConsole.OrganizationFeatures.Policies; using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements; using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
using Bit.Core.AdminConsole.Services; using Bit.Core.AdminConsole.Services;
using Bit.Core.Context;
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Platform.Push; using Bit.Core.Platform.Push;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.ImportFeatures.Interfaces; using Bit.Core.Tools.ImportFeatures.Interfaces;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Vault.Entities; using Bit.Core.Vault.Entities;
using Bit.Core.Vault.Models.Data; using Bit.Core.Vault.Models.Data;
using Bit.Core.Vault.Repositories; using Bit.Core.Vault.Repositories;
@ -27,8 +23,6 @@ public class ImportCiphersCommand : IImportCiphersCommand
private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationUserRepository _organizationUserRepository; private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly ICollectionRepository _collectionRepository; private readonly ICollectionRepository _collectionRepository;
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext;
private readonly IPolicyRequirementQuery _policyRequirementQuery; private readonly IPolicyRequirementQuery _policyRequirementQuery;
private readonly IFeatureService _featureService; private readonly IFeatureService _featureService;
@ -40,8 +34,6 @@ public class ImportCiphersCommand : IImportCiphersCommand
IOrganizationUserRepository organizationUserRepository, IOrganizationUserRepository organizationUserRepository,
IPushNotificationService pushService, IPushNotificationService pushService,
IPolicyService policyService, IPolicyService policyService,
IReferenceEventService referenceEventService,
ICurrentContext currentContext,
IPolicyRequirementQuery policyRequirementQuery, IPolicyRequirementQuery policyRequirementQuery,
IFeatureService featureService) IFeatureService featureService)
{ {
@ -52,8 +44,6 @@ public class ImportCiphersCommand : IImportCiphersCommand
_collectionRepository = collectionRepository; _collectionRepository = collectionRepository;
_pushService = pushService; _pushService = pushService;
_policyService = policyService; _policyService = policyService;
_referenceEventService = referenceEventService;
_currentContext = currentContext;
_policyRequirementQuery = policyRequirementQuery; _policyRequirementQuery = policyRequirementQuery;
_featureService = featureService; _featureService = featureService;
} }
@ -194,12 +184,5 @@ public class ImportCiphersCommand : IImportCiphersCommand
// push // push
await _pushService.PushSyncVaultAsync(importingUserId); await _pushService.PushSyncVaultAsync(importingUserId);
if (org != null)
{
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.VaultImported, org, _currentContext));
}
} }
} }

View File

@ -1,274 +0,0 @@
#nullable enable
using System.Text.Json.Serialization;
using Bit.Core.Billing.Enums;
using Bit.Core.Context;
using Bit.Core.Tools.Entities;
using Bit.Core.Tools.Enums;
namespace Bit.Core.Tools.Models.Business;
/// <summary>
/// Product support monitoring.
/// </summary>
/// <remarks>
/// Do not store secrets in this type.
/// </remarks>
public class ReferenceEvent
{
/// <summary>
/// Instantiates a <see cref="ReferenceEvent"/>.
/// </summary>
public ReferenceEvent() { }
/// <inheritdoc cref="ReferenceEvent()" />
/// <param name="type">Monitored event type.</param>
/// <param name="source">Entity that created the event.</param>
/// <param name="currentContext">The conditions in which the event occurred.</param>
public ReferenceEvent(ReferenceEventType type, IReferenceable source, ICurrentContext currentContext)
{
Type = type;
if (source != null)
{
Source = source.IsUser() ? ReferenceEventSource.User : ReferenceEventSource.Organization;
Id = source.Id;
ReferenceData = source.ReferenceData;
}
if (currentContext != null)
{
ClientId = currentContext.ClientId;
ClientVersion = currentContext.ClientVersion;
}
}
/// <summary>
/// Monitored event type.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public ReferenceEventType Type { get; set; }
/// <summary>
/// The kind of entity that created the event.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public ReferenceEventSource Source { get; set; }
/// <inheritdoc cref="IReferenceable.Id"/>
public Guid Id { get; set; }
/// <inheritdoc cref="IReferenceable.ReferenceData"/>
public string? ReferenceData { get; set; }
/// <summary>
/// Moment the event occurred.
/// </summary>
public DateTime EventDate { get; set; } = DateTime.UtcNow;
/// <summary>
/// Number of users sent invitations by an organization.
/// </summary>
/// <value>
/// Should contain a value only on <see cref="ReferenceEventType.InvitedUsers"/> events.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public int? Users { get; set; }
/// <summary>
/// Whether or not a subscription was canceled immediately or at the end of the billing period.
/// </summary>
/// <value>
/// <see langword="true"/> when a cancellation occurs immediately.
/// <see langword="false"/> when a cancellation occurs at the end of a customer's billing period.
/// Should contain a value only on <see cref="ReferenceEventType.CancelSubscription"/> events.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public bool? EndOfPeriod { get; set; }
/// <summary>
/// Branded name of the subscription.
/// </summary>
/// <value>
/// Should contain a value only for subscription management events.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public string? PlanName { get; set; }
/// <summary>
/// Identifies a subscription.
/// </summary>
/// <value>
/// Should contain a value only for subscription management events.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public PlanType? PlanType { get; set; }
/// <summary>
/// The branded name of the prior plan.
/// </summary>
/// <value>
/// Should contain a value only on <see cref="ReferenceEventType.UpgradePlan"/> events
/// initiated by organizations.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public string? OldPlanName { get; set; }
/// <summary>
/// Identifies the prior plan
/// </summary>
/// <value>
/// Should contain a value only on <see cref="ReferenceEventType.UpgradePlan"/> events
/// initiated by organizations.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public PlanType? OldPlanType { get; set; }
/// <summary>
/// Seat count when a billable action occurs. When adjusting seats, contains
/// the new seat count.
/// </summary>
/// <value>
/// Should contain a value only on <see cref="ReferenceEventType.Rebilled"/>,
/// <see cref="ReferenceEventType.AdjustSeats"/>, <see cref="ReferenceEventType.UpgradePlan"/>,
/// and <see cref="ReferenceEventType.Signup"/> events initiated by organizations.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public int? Seats { get; set; }
/// <summary>
/// Seat count when a seat adjustment occurs.
/// </summary>
/// <value>
/// Should contain a value only on <see cref="ReferenceEventType.AdjustSeats"/>
/// events initiated by organizations.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public int? PreviousSeats { get; set; }
/// <summary>
/// Qty in GB of storage. When adjusting storage, contains the adjusted
/// storage qty. Otherwise contains the total storage quantity.
/// </summary>
/// <value>
/// Should contain a value only on <see cref="ReferenceEventType.Rebilled"/>,
/// <see cref="ReferenceEventType.AdjustStorage"/>, <see cref="ReferenceEventType.UpgradePlan"/>,
/// and <see cref="ReferenceEventType.Signup"/> events.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public short? Storage { get; set; }
/// <summary>
/// The type of send created or accessed.
/// </summary>
/// <value>
/// Should contain a value only on <see cref="ReferenceEventType.SendAccessed"/>
/// and <see cref="ReferenceEventType.SendCreated"/> events.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
[JsonConverter(typeof(JsonStringEnumConverter))]
public SendType? SendType { get; set; }
/// <summary>
/// Whether the send has private notes.
/// </summary>
/// <value>
/// <see langword="true"/> when the send has private notes, otherwise <see langword="false"/>.
/// Should contain a value only on <see cref="ReferenceEventType.SendAccessed"/>
/// and <see cref="ReferenceEventType.SendCreated"/> events.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public bool? SendHasNotes { get; set; }
/// <summary>
/// The send expires after its access count exceeds this value.
/// </summary>
/// <value>
/// This field only contains a value when the send has a max access count
/// and <see cref="Type"/> is <see cref="ReferenceEventType.SendAccessed"/>
/// or <see cref="ReferenceEventType.SendCreated"/> events.
/// Otherwise, the value should be <see langword="null"/>.
/// </value>
public int? MaxAccessCount { get; set; }
/// <summary>
/// Whether the created send has a password.
/// </summary>
/// <value>
/// Should contain a value only on <see cref="ReferenceEventType.SendAccessed"/>
/// and <see cref="ReferenceEventType.SendCreated"/> events.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public bool? HasPassword { get; set; }
/// <summary>
/// The administrator that performed the action.
/// </summary>
/// <value>
/// Should contain a value only on <see cref="ReferenceEventType.OrganizationCreatedByAdmin"/>
/// and <see cref="ReferenceEventType.OrganizationEditedByAdmin"/> events.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public string? EventRaisedByUser { get; set; }
/// <summary>
/// Whether or not an organization's trial period was started by a sales person.
/// </summary>
/// <value>
/// Should contain a value only on <see cref="ReferenceEventType.OrganizationCreatedByAdmin"/>
/// and <see cref="ReferenceEventType.OrganizationEditedByAdmin"/> events.
/// Otherwise the value should be <see langword="null"/>.
/// </value>
public bool? SalesAssistedTrialStarted { get; set; }
/// <summary>
/// The installation id of the application that originated the event.
/// </summary>
/// <value>
/// <see langword="null"/> when the event was not originated by an application.
/// </value>
public string? ClientId { get; set; }
/// <summary>
/// The version of the client application that originated the event.
/// </summary>
/// <value>
/// <see langword="null"/> when the event was not originated by an application.
/// </value>
public Version? ClientVersion { get; set; }
/// <summary>
/// The initiation path of a user who signed up for a paid version of Bitwarden. For example, "Trial from marketing website".
/// </summary>
/// <value>
/// This value should only be populated when the <see cref="ReferenceEventType"/> is <see cref="ReferenceEventType.Signup"/>. Otherwise,
/// the value should be <see langword="null" />.
/// </value>
public string? SignupInitiationPath { get; set; }
/// <summary>
/// The upgrade applied to an account. The current plan is listed first,
/// followed by the plan they are migrating to. For example,
/// "Teams Starter → Teams, Enterprise".
/// </summary>
/// <value>
/// <see langword="null"/> when the event was not originated by an application,
/// or when a downgrade occurred.
/// </value>
public string? PlanUpgradePath { get; set; }
/// <summary>
/// Used for the <see cref="ReferenceEventType.Signup"/> event to determine if the user has opted in to marketing emails.
/// </summary>
public bool? ReceiveMarketingEmails { get; set; }
/// <summary>
/// Used for the <see cref="ReferenceEventType.SignupEmailClicked"/> event to indicate if the user
/// landed on the registration finish screen with a valid or invalid email verification token.
/// </summary>
public bool? EmailVerificationTokenValid { get; set; }
/// <summary>
/// Used for the <see cref="ReferenceEventType.SignupEmailClicked"/> event to indicate if the user
/// landed on the registration finish screen after re-clicking an already used link.
/// </summary>
public bool? UserAlreadyExists { get; set; }
}

View File

@ -1,10 +1,8 @@
using System.Text.Json; using System.Text.Json;
using Bit.Core.Context;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Platform.Push; using Bit.Core.Platform.Push;
using Bit.Core.Tools.Entities; using Bit.Core.Tools.Entities;
using Bit.Core.Tools.Enums; using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Models.Data; using Bit.Core.Tools.Models.Data;
using Bit.Core.Tools.Repositories; using Bit.Core.Tools.Repositories;
using Bit.Core.Tools.SendFeatures.Commands.Interfaces; using Bit.Core.Tools.SendFeatures.Commands.Interfaces;
@ -19,8 +17,6 @@ public class NonAnonymousSendCommand : INonAnonymousSendCommand
private readonly ISendFileStorageService _sendFileStorageService; private readonly ISendFileStorageService _sendFileStorageService;
private readonly IPushNotificationService _pushNotificationService; private readonly IPushNotificationService _pushNotificationService;
private readonly ISendValidationService _sendValidationService; private readonly ISendValidationService _sendValidationService;
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext;
private readonly ISendCoreHelperService _sendCoreHelperService; private readonly ISendCoreHelperService _sendCoreHelperService;
public NonAnonymousSendCommand(ISendRepository sendRepository, public NonAnonymousSendCommand(ISendRepository sendRepository,
@ -28,16 +24,12 @@ public class NonAnonymousSendCommand : INonAnonymousSendCommand
IPushNotificationService pushNotificationService, IPushNotificationService pushNotificationService,
ISendAuthorizationService sendAuthorizationService, ISendAuthorizationService sendAuthorizationService,
ISendValidationService sendValidationService, ISendValidationService sendValidationService,
IReferenceEventService referenceEventService,
ICurrentContext currentContext,
ISendCoreHelperService sendCoreHelperService) ISendCoreHelperService sendCoreHelperService)
{ {
_sendRepository = sendRepository; _sendRepository = sendRepository;
_sendFileStorageService = sendFileStorageService; _sendFileStorageService = sendFileStorageService;
_pushNotificationService = pushNotificationService; _pushNotificationService = pushNotificationService;
_sendValidationService = sendValidationService; _sendValidationService = sendValidationService;
_referenceEventService = referenceEventService;
_currentContext = currentContext;
_sendCoreHelperService = sendCoreHelperService; _sendCoreHelperService = sendCoreHelperService;
} }
@ -50,18 +42,6 @@ public class NonAnonymousSendCommand : INonAnonymousSendCommand
{ {
await _sendRepository.CreateAsync(send); await _sendRepository.CreateAsync(send);
await _pushNotificationService.PushSyncSendCreateAsync(send); await _pushNotificationService.PushSyncSendCreateAsync(send);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent
{
Id = send.UserId ?? default,
Type = ReferenceEventType.SendCreated,
Source = ReferenceEventSource.User,
SendType = send.Type,
MaxAccessCount = send.MaxAccessCount,
HasPassword = !string.IsNullOrWhiteSpace(send.Password),
SendHasNotes = send.Data?.Contains("Notes"),
ClientId = _currentContext.ClientId,
ClientVersion = _currentContext.ClientVersion
});
} }
else else
{ {

View File

@ -1,9 +1,7 @@
using Bit.Core.Context; using Bit.Core.Entities;
using Bit.Core.Entities;
using Bit.Core.Platform.Push; using Bit.Core.Platform.Push;
using Bit.Core.Tools.Entities; using Bit.Core.Tools.Entities;
using Bit.Core.Tools.Enums; using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Models.Data; using Bit.Core.Tools.Models.Data;
using Bit.Core.Tools.Repositories; using Bit.Core.Tools.Repositories;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
@ -15,21 +13,15 @@ public class SendAuthorizationService : ISendAuthorizationService
private readonly ISendRepository _sendRepository; private readonly ISendRepository _sendRepository;
private readonly IPasswordHasher<User> _passwordHasher; private readonly IPasswordHasher<User> _passwordHasher;
private readonly IPushNotificationService _pushNotificationService; private readonly IPushNotificationService _pushNotificationService;
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext;
public SendAuthorizationService( public SendAuthorizationService(
ISendRepository sendRepository, ISendRepository sendRepository,
IPasswordHasher<User> passwordHasher, IPasswordHasher<User> passwordHasher,
IPushNotificationService pushNotificationService, IPushNotificationService pushNotificationService)
IReferenceEventService referenceEventService,
ICurrentContext currentContext)
{ {
_sendRepository = sendRepository; _sendRepository = sendRepository;
_passwordHasher = passwordHasher; _passwordHasher = passwordHasher;
_pushNotificationService = pushNotificationService; _pushNotificationService = pushNotificationService;
_referenceEventService = referenceEventService;
_currentContext = currentContext;
} }
public SendAccessResult SendCanBeAccessed(Send send, public SendAccessResult SendCanBeAccessed(Send send,
@ -79,18 +71,6 @@ public class SendAuthorizationService : ISendAuthorizationService
await _sendRepository.ReplaceAsync(sendToBeAccessed); await _sendRepository.ReplaceAsync(sendToBeAccessed);
await _pushNotificationService.PushSyncSendUpdateAsync(sendToBeAccessed); await _pushNotificationService.PushSyncSendUpdateAsync(sendToBeAccessed);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent
{
Id = sendToBeAccessed.UserId ?? default,
Type = ReferenceEventType.SendAccessed,
Source = ReferenceEventSource.User,
SendType = sendToBeAccessed.Type,
MaxAccessCount = sendToBeAccessed.MaxAccessCount,
HasPassword = !string.IsNullOrWhiteSpace(sendToBeAccessed.Password),
SendHasNotes = sendToBeAccessed.Data?.Contains("Notes"),
ClientId = _currentContext.ClientId,
ClientVersion = _currentContext.ClientVersion
});
return accessResult; return accessResult;
} }

View File

@ -1,8 +0,0 @@
using Bit.Core.Tools.Models.Business;
namespace Bit.Core.Tools.Services;
public interface IReferenceEventService
{
Task RaiseEventAsync(ReferenceEvent referenceEvent);
}

View File

@ -1,48 +0,0 @@
using System.Text;
using System.Text.Json;
using Azure.Storage.Queues;
using Bit.Core.Settings;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Utilities;
namespace Bit.Core.Tools.Services;
public class AzureQueueReferenceEventService : IReferenceEventService
{
private const string _queueName = "reference-events";
private readonly QueueClient _queueClient;
private readonly GlobalSettings _globalSettings;
public AzureQueueReferenceEventService(
GlobalSettings globalSettings)
{
_queueClient = new QueueClient(globalSettings.Events.ConnectionString, _queueName);
_globalSettings = globalSettings;
}
public async Task RaiseEventAsync(ReferenceEvent referenceEvent)
{
await SendMessageAsync(referenceEvent);
}
private async Task SendMessageAsync(ReferenceEvent referenceEvent)
{
if (_globalSettings.SelfHosted)
{
// Ignore for self-hosted
return;
}
try
{
var message = JsonSerializer.Serialize(referenceEvent, JsonHelpers.IgnoreWritingNullAndCamelCase);
// Messages need to be base64 encoded
var encodedMessage = Convert.ToBase64String(Encoding.UTF8.GetBytes(message));
await _queueClient.SendMessageAsync(encodedMessage);
}
catch
{
// Ignore failure
}
}
}

View File

@ -1,11 +0,0 @@
using Bit.Core.Tools.Models.Business;
namespace Bit.Core.Tools.Services;
public class NoopReferenceEventService : IReferenceEventService
{
public Task RaiseEventAsync(ReferenceEvent referenceEvent)
{
return Task.CompletedTask;
}
}

View File

@ -3,16 +3,12 @@ using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies; using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements; using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
using Bit.Core.AdminConsole.Services; using Bit.Core.AdminConsole.Services;
using Bit.Core.Context;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Platform.Push; using Bit.Core.Platform.Push;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Core.Vault.Authorization.Permissions; using Bit.Core.Vault.Authorization.Permissions;
using Bit.Core.Vault.Entities; using Bit.Core.Vault.Entities;
@ -41,8 +37,6 @@ public class CipherService : ICipherService
private readonly IPolicyService _policyService; private readonly IPolicyService _policyService;
private readonly GlobalSettings _globalSettings; private readonly GlobalSettings _globalSettings;
private const long _fileSizeLeeway = 1024L * 1024L; // 1MB private const long _fileSizeLeeway = 1024L * 1024L; // 1MB
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext;
private readonly IGetCipherPermissionsForUserQuery _getCipherPermissionsForUserQuery; private readonly IGetCipherPermissionsForUserQuery _getCipherPermissionsForUserQuery;
private readonly IPolicyRequirementQuery _policyRequirementQuery; private readonly IPolicyRequirementQuery _policyRequirementQuery;
private readonly IApplicationCacheService _applicationCacheService; private readonly IApplicationCacheService _applicationCacheService;
@ -62,8 +56,6 @@ public class CipherService : ICipherService
IUserService userService, IUserService userService,
IPolicyService policyService, IPolicyService policyService,
GlobalSettings globalSettings, GlobalSettings globalSettings,
IReferenceEventService referenceEventService,
ICurrentContext currentContext,
IGetCipherPermissionsForUserQuery getCipherPermissionsForUserQuery, IGetCipherPermissionsForUserQuery getCipherPermissionsForUserQuery,
IPolicyRequirementQuery policyRequirementQuery, IPolicyRequirementQuery policyRequirementQuery,
IApplicationCacheService applicationCacheService, IApplicationCacheService applicationCacheService,
@ -82,8 +74,6 @@ public class CipherService : ICipherService
_userService = userService; _userService = userService;
_policyService = policyService; _policyService = policyService;
_globalSettings = globalSettings; _globalSettings = globalSettings;
_referenceEventService = referenceEventService;
_currentContext = currentContext;
_getCipherPermissionsForUserQuery = getCipherPermissionsForUserQuery; _getCipherPermissionsForUserQuery = getCipherPermissionsForUserQuery;
_policyRequirementQuery = policyRequirementQuery; _policyRequirementQuery = policyRequirementQuery;
_applicationCacheService = applicationCacheService; _applicationCacheService = applicationCacheService;
@ -108,9 +98,6 @@ public class CipherService : ICipherService
cipher.UserId = savingUserId; cipher.UserId = savingUserId;
} }
await _cipherRepository.CreateAsync(cipher, collectionIds); await _cipherRepository.CreateAsync(cipher, collectionIds);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.CipherCreated, await _organizationRepository.GetByIdAsync(cipher.OrganizationId.Value), _currentContext));
} }
else else
{ {

View File

@ -1,11 +1,7 @@
using Bit.Core; using Bit.Core;
using Bit.Core.Billing.Models.Api.Requests.Accounts; using Bit.Core.Billing.Models.Api.Requests.Accounts;
using Bit.Core.Billing.TrialInitiation.Registration; using Bit.Core.Billing.TrialInitiation.Registration;
using Bit.Core.Context;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.SharedWeb.Utilities; using Bit.SharedWeb.Utilities;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -15,9 +11,7 @@ namespace Bit.Identity.Billing.Controller;
[Route("accounts")] [Route("accounts")]
[ExceptionHandlerFilter] [ExceptionHandlerFilter]
public class AccountsController( public class AccountsController(
ICurrentContext currentContext,
ISendTrialInitiationEmailForRegistrationCommand sendTrialInitiationEmailForRegistrationCommand, ISendTrialInitiationEmailForRegistrationCommand sendTrialInitiationEmailForRegistrationCommand,
IReferenceEventService referenceEventService,
IFeatureService featureService) : Microsoft.AspNetCore.Mvc.Controller IFeatureService featureService) : Microsoft.AspNetCore.Mvc.Controller
{ {
[HttpPost("trial/send-verification-email")] [HttpPost("trial/send-verification-email")]
@ -36,15 +30,6 @@ public class AccountsController(
model.Products, model.Products,
trialLength); trialLength);
var refEvent = new ReferenceEvent
{
Type = ReferenceEventType.SignupEmailSubmit,
ClientId = currentContext.ClientId,
ClientVersion = currentContext.ClientVersion,
Source = ReferenceEventSource.Registration
};
await referenceEventService.RaiseEventAsync(refEvent);
if (token != null) if (token != null)
{ {
return Ok(token); return Ok(token);

View File

@ -16,9 +16,6 @@ using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tokens; using Bit.Core.Tokens;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Identity.Models.Request.Accounts; using Bit.Identity.Models.Request.Accounts;
using Bit.Identity.Models.Response.Accounts; using Bit.Identity.Models.Response.Accounts;
@ -39,7 +36,6 @@ public class AccountsController : Controller
private readonly IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable> _assertionOptionsDataProtector; private readonly IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable> _assertionOptionsDataProtector;
private readonly IGetWebAuthnLoginCredentialAssertionOptionsCommand _getWebAuthnLoginCredentialAssertionOptionsCommand; private readonly IGetWebAuthnLoginCredentialAssertionOptionsCommand _getWebAuthnLoginCredentialAssertionOptionsCommand;
private readonly ISendVerificationEmailForRegistrationCommand _sendVerificationEmailForRegistrationCommand; private readonly ISendVerificationEmailForRegistrationCommand _sendVerificationEmailForRegistrationCommand;
private readonly IReferenceEventService _referenceEventService;
private readonly IFeatureService _featureService; private readonly IFeatureService _featureService;
private readonly IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> _registrationEmailVerificationTokenDataFactory; private readonly IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> _registrationEmailVerificationTokenDataFactory;
@ -86,7 +82,6 @@ public class AccountsController : Controller
IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable> assertionOptionsDataProtector, IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable> assertionOptionsDataProtector,
IGetWebAuthnLoginCredentialAssertionOptionsCommand getWebAuthnLoginCredentialAssertionOptionsCommand, IGetWebAuthnLoginCredentialAssertionOptionsCommand getWebAuthnLoginCredentialAssertionOptionsCommand,
ISendVerificationEmailForRegistrationCommand sendVerificationEmailForRegistrationCommand, ISendVerificationEmailForRegistrationCommand sendVerificationEmailForRegistrationCommand,
IReferenceEventService referenceEventService,
IFeatureService featureService, IFeatureService featureService,
IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> registrationEmailVerificationTokenDataFactory, IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> registrationEmailVerificationTokenDataFactory,
GlobalSettings globalSettings GlobalSettings globalSettings
@ -99,7 +94,6 @@ public class AccountsController : Controller
_assertionOptionsDataProtector = assertionOptionsDataProtector; _assertionOptionsDataProtector = assertionOptionsDataProtector;
_getWebAuthnLoginCredentialAssertionOptionsCommand = getWebAuthnLoginCredentialAssertionOptionsCommand; _getWebAuthnLoginCredentialAssertionOptionsCommand = getWebAuthnLoginCredentialAssertionOptionsCommand;
_sendVerificationEmailForRegistrationCommand = sendVerificationEmailForRegistrationCommand; _sendVerificationEmailForRegistrationCommand = sendVerificationEmailForRegistrationCommand;
_referenceEventService = referenceEventService;
_featureService = featureService; _featureService = featureService;
_registrationEmailVerificationTokenDataFactory = registrationEmailVerificationTokenDataFactory; _registrationEmailVerificationTokenDataFactory = registrationEmailVerificationTokenDataFactory;
@ -115,15 +109,6 @@ public class AccountsController : Controller
var token = await _sendVerificationEmailForRegistrationCommand.Run(model.Email, model.Name, var token = await _sendVerificationEmailForRegistrationCommand.Run(model.Email, model.Name,
model.ReceiveMarketingEmails); model.ReceiveMarketingEmails);
var refEvent = new ReferenceEvent
{
Type = ReferenceEventType.SignupEmailSubmit,
ClientId = _currentContext.ClientId,
ClientVersion = _currentContext.ClientVersion,
Source = ReferenceEventSource.Registration
};
await _referenceEventService.RaiseEventAsync(refEvent);
if (token != null) if (token != null)
{ {
return Ok(token); return Ok(token);
@ -142,18 +127,6 @@ public class AccountsController : Controller
var user = await _userRepository.GetByEmailAsync(model.Email); var user = await _userRepository.GetByEmailAsync(model.Email);
var userExists = user != null; var userExists = user != null;
var refEvent = new ReferenceEvent
{
Type = ReferenceEventType.SignupEmailClicked,
ClientId = _currentContext.ClientId,
ClientVersion = _currentContext.ClientVersion,
Source = ReferenceEventSource.Registration,
EmailVerificationTokenValid = tokenValid,
UserAlreadyExists = userExists
};
await _referenceEventService.RaiseEventAsync(refEvent);
if (!tokenValid || userExists) if (!tokenValid || userExists)
{ {
throw new BadRequestException("Expired link. Please restart registration or try logging in. You may already have an account"); throw new BadRequestException("Expired link. Please restart registration or try logging in. You may already have an account");

View File

@ -352,15 +352,6 @@ public static class ServiceCollectionExtensions
{ {
services.AddSingleton<ISendFileStorageService, NoopSendFileStorageService>(); services.AddSingleton<ISendFileStorageService, NoopSendFileStorageService>();
} }
if (globalSettings.SelfHosted)
{
services.AddSingleton<IReferenceEventService, NoopReferenceEventService>();
}
else
{
services.AddSingleton<IReferenceEventService, AzureQueueReferenceEventService>();
}
} }
public static void AddOosServices(this IServiceCollection services) public static void AddOosServices(this IServiceCollection services)

View File

@ -23,7 +23,6 @@ using Bit.Core.OrganizationFeatures.OrganizationLicenses.Interfaces;
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface; using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Services;
using NSubstitute; using NSubstitute;
using NSubstitute.ReturnsExtensions; using NSubstitute.ReturnsExtensions;
using Xunit; using Xunit;
@ -46,7 +45,6 @@ public class OrganizationsControllerTests : IDisposable
private readonly IUpdateSecretsManagerSubscriptionCommand _updateSecretsManagerSubscriptionCommand; private readonly IUpdateSecretsManagerSubscriptionCommand _updateSecretsManagerSubscriptionCommand;
private readonly IUpgradeOrganizationPlanCommand _upgradeOrganizationPlanCommand; private readonly IUpgradeOrganizationPlanCommand _upgradeOrganizationPlanCommand;
private readonly IAddSecretsManagerSubscriptionCommand _addSecretsManagerSubscriptionCommand; private readonly IAddSecretsManagerSubscriptionCommand _addSecretsManagerSubscriptionCommand;
private readonly IReferenceEventService _referenceEventService;
private readonly ISubscriberService _subscriberService; private readonly ISubscriberService _subscriberService;
private readonly IRemoveOrganizationUserCommand _removeOrganizationUserCommand; private readonly IRemoveOrganizationUserCommand _removeOrganizationUserCommand;
private readonly IOrganizationInstallationRepository _organizationInstallationRepository; private readonly IOrganizationInstallationRepository _organizationInstallationRepository;
@ -71,7 +69,6 @@ public class OrganizationsControllerTests : IDisposable
_updateSecretsManagerSubscriptionCommand = Substitute.For<IUpdateSecretsManagerSubscriptionCommand>(); _updateSecretsManagerSubscriptionCommand = Substitute.For<IUpdateSecretsManagerSubscriptionCommand>();
_upgradeOrganizationPlanCommand = Substitute.For<IUpgradeOrganizationPlanCommand>(); _upgradeOrganizationPlanCommand = Substitute.For<IUpgradeOrganizationPlanCommand>();
_addSecretsManagerSubscriptionCommand = Substitute.For<IAddSecretsManagerSubscriptionCommand>(); _addSecretsManagerSubscriptionCommand = Substitute.For<IAddSecretsManagerSubscriptionCommand>();
_referenceEventService = Substitute.For<IReferenceEventService>();
_subscriberService = Substitute.For<ISubscriberService>(); _subscriberService = Substitute.For<ISubscriberService>();
_removeOrganizationUserCommand = Substitute.For<IRemoveOrganizationUserCommand>(); _removeOrganizationUserCommand = Substitute.For<IRemoveOrganizationUserCommand>();
_organizationInstallationRepository = Substitute.For<IOrganizationInstallationRepository>(); _organizationInstallationRepository = Substitute.For<IOrganizationInstallationRepository>();
@ -90,7 +87,6 @@ public class OrganizationsControllerTests : IDisposable
_updateSecretsManagerSubscriptionCommand, _updateSecretsManagerSubscriptionCommand,
_upgradeOrganizationPlanCommand, _upgradeOrganizationPlanCommand,
_addSecretsManagerSubscriptionCommand, _addSecretsManagerSubscriptionCommand,
_referenceEventService,
_subscriberService, _subscriberService,
_organizationInstallationRepository, _organizationInstallationRepository,
_pricingClient); _pricingClient);

View File

@ -3,7 +3,6 @@ using AutoFixture.Xunit2;
using Bit.Api.Tools.Controllers; using Bit.Api.Tools.Controllers;
using Bit.Api.Tools.Models.Request; using Bit.Api.Tools.Models.Request;
using Bit.Api.Tools.Models.Response; using Bit.Api.Tools.Models.Response;
using Bit.Core.Context;
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Services; using Bit.Core.Services;
@ -33,7 +32,6 @@ public class SendsControllerTests : IDisposable
private readonly ISendAuthorizationService _sendAuthorizationService; private readonly ISendAuthorizationService _sendAuthorizationService;
private readonly ISendFileStorageService _sendFileStorageService; private readonly ISendFileStorageService _sendFileStorageService;
private readonly ILogger<SendsController> _logger; private readonly ILogger<SendsController> _logger;
private readonly ICurrentContext _currentContext;
public SendsControllerTests() public SendsControllerTests()
{ {
@ -45,7 +43,6 @@ public class SendsControllerTests : IDisposable
_sendFileStorageService = Substitute.For<ISendFileStorageService>(); _sendFileStorageService = Substitute.For<ISendFileStorageService>();
_globalSettings = new GlobalSettings(); _globalSettings = new GlobalSettings();
_logger = Substitute.For<ILogger<SendsController>>(); _logger = Substitute.For<ILogger<SendsController>>();
_currentContext = Substitute.For<ICurrentContext>();
_sut = new SendsController( _sut = new SendsController(
_sendRepository, _sendRepository,
@ -55,8 +52,7 @@ public class SendsControllerTests : IDisposable
_nonAnonymousSendCommand, _nonAnonymousSendCommand,
_sendFileStorageService, _sendFileStorageService,
_logger, _logger,
_globalSettings, _globalSettings
_currentContext
); );
} }

View File

@ -6,9 +6,6 @@ using Bit.Core.Exceptions;
using Bit.Core.Models.Data; using Bit.Core.Models.Data;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Test.AutoFixture.OrganizationFixtures; using Bit.Core.Test.AutoFixture.OrganizationFixtures;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.AutoFixture.Attributes;
using Bit.Test.Common.Helpers; using Bit.Test.Common.Helpers;
@ -27,7 +24,6 @@ public class CreateGroupCommandTests
await sutProvider.GetDependency<IGroupRepository>().Received(1).CreateAsync(group); await sutProvider.GetDependency<IGroupRepository>().Received(1).CreateAsync(group);
await sutProvider.GetDependency<IEventService>().Received(1).LogGroupEventAsync(group, Enums.EventType.Group_Created); await sutProvider.GetDependency<IEventService>().Received(1).LogGroupEventAsync(group, Enums.EventType.Group_Created);
await sutProvider.GetDependency<IReferenceEventService>().Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(r => r.Type == ReferenceEventType.GroupCreated && r.Id == organization.Id && r.Source == ReferenceEventSource.Organization));
AssertHelper.AssertRecent(group.CreationDate); AssertHelper.AssertRecent(group.CreationDate);
AssertHelper.AssertRecent(group.RevisionDate); AssertHelper.AssertRecent(group.RevisionDate);
} }
@ -48,7 +44,6 @@ public class CreateGroupCommandTests
await sutProvider.GetDependency<IGroupRepository>().Received(1).CreateAsync(group, collections); await sutProvider.GetDependency<IGroupRepository>().Received(1).CreateAsync(group, collections);
await sutProvider.GetDependency<IEventService>().Received(1).LogGroupEventAsync(group, Enums.EventType.Group_Created); await sutProvider.GetDependency<IEventService>().Received(1).LogGroupEventAsync(group, Enums.EventType.Group_Created);
await sutProvider.GetDependency<IReferenceEventService>().Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(r => r.Type == ReferenceEventType.GroupCreated && r.Id == organization.Id && r.Source == ReferenceEventSource.Organization));
AssertHelper.AssertRecent(group.CreationDate); AssertHelper.AssertRecent(group.CreationDate);
AssertHelper.AssertRecent(group.RevisionDate); AssertHelper.AssertRecent(group.RevisionDate);
} }
@ -60,7 +55,6 @@ public class CreateGroupCommandTests
await sutProvider.GetDependency<IGroupRepository>().Received(1).CreateAsync(group); await sutProvider.GetDependency<IGroupRepository>().Received(1).CreateAsync(group);
await sutProvider.GetDependency<IEventService>().Received(1).LogGroupEventAsync(group, Enums.EventType.Group_Created, eventSystemUser); await sutProvider.GetDependency<IEventService>().Received(1).LogGroupEventAsync(group, Enums.EventType.Group_Created, eventSystemUser);
await sutProvider.GetDependency<IReferenceEventService>().Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(r => r.Type == ReferenceEventType.GroupCreated && r.Id == organization.Id && r.Source == ReferenceEventSource.Organization));
AssertHelper.AssertRecent(group.CreationDate); AssertHelper.AssertRecent(group.CreationDate);
AssertHelper.AssertRecent(group.RevisionDate); AssertHelper.AssertRecent(group.RevisionDate);
} }
@ -74,7 +68,6 @@ public class CreateGroupCommandTests
await sutProvider.GetDependency<IGroupRepository>().DidNotReceiveWithAnyArgs().CreateAsync(default); await sutProvider.GetDependency<IGroupRepository>().DidNotReceiveWithAnyArgs().CreateAsync(default);
await sutProvider.GetDependency<IEventService>().DidNotReceiveWithAnyArgs().LogGroupEventAsync(default, default, default); await sutProvider.GetDependency<IEventService>().DidNotReceiveWithAnyArgs().LogGroupEventAsync(default, default, default);
await sutProvider.GetDependency<IReferenceEventService>().DidNotReceiveWithAnyArgs().RaiseEventAsync(default);
} }
[Theory, OrganizationCustomize(UseGroups = false), BitAutoData] [Theory, OrganizationCustomize(UseGroups = false), BitAutoData]
@ -86,6 +79,5 @@ public class CreateGroupCommandTests
await sutProvider.GetDependency<IGroupRepository>().DidNotReceiveWithAnyArgs().CreateAsync(default); await sutProvider.GetDependency<IGroupRepository>().DidNotReceiveWithAnyArgs().CreateAsync(default);
await sutProvider.GetDependency<IEventService>().DidNotReceiveWithAnyArgs().LogGroupEventAsync(default, default, default); await sutProvider.GetDependency<IEventService>().DidNotReceiveWithAnyArgs().LogGroupEventAsync(default, default, default);
await sutProvider.GetDependency<IReferenceEventService>().DidNotReceiveWithAnyArgs().RaiseEventAsync(default);
} }
} }

View File

@ -10,9 +10,6 @@ using Bit.Core.Exceptions;
using Bit.Core.Models.Business; using Bit.Core.Models.Business;
using Bit.Core.Models.Data; using Bit.Core.Models.Data;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.AutoFixture.Attributes;
@ -51,15 +48,6 @@ public class CloudICloudOrganizationSignUpCommandTests
await sutProvider.GetDependency<IOrganizationUserRepository>().Received(1).CreateAsync( await sutProvider.GetDependency<IOrganizationUserRepository>().Received(1).CreateAsync(
Arg.Is<OrganizationUser>(o => o.AccessSecretsManager == signup.UseSecretsManager)); Arg.Is<OrganizationUser>(o => o.AccessSecretsManager == signup.UseSecretsManager));
await sutProvider.GetDependency<IReferenceEventService>().Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(referenceEvent =>
referenceEvent.Type == ReferenceEventType.Signup &&
referenceEvent.PlanName == plan.Name &&
referenceEvent.PlanType == plan.Type &&
referenceEvent.Seats == result.Organization.Seats &&
referenceEvent.Storage == result.Organization.MaxStorageGb));
// TODO: add reference events for SmSeats and Service Accounts - see AC-1481
Assert.NotNull(result.Organization); Assert.NotNull(result.Organization);
Assert.NotNull(result.OrganizationUser); Assert.NotNull(result.OrganizationUser);
@ -145,15 +133,6 @@ public class CloudICloudOrganizationSignUpCommandTests
await sutProvider.GetDependency<IOrganizationUserRepository>().Received(1).CreateAsync( await sutProvider.GetDependency<IOrganizationUserRepository>().Received(1).CreateAsync(
Arg.Is<OrganizationUser>(o => o.AccessSecretsManager == signup.UseSecretsManager)); Arg.Is<OrganizationUser>(o => o.AccessSecretsManager == signup.UseSecretsManager));
await sutProvider.GetDependency<IReferenceEventService>().Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(referenceEvent =>
referenceEvent.Type == ReferenceEventType.Signup &&
referenceEvent.PlanName == plan.Name &&
referenceEvent.PlanType == plan.Type &&
referenceEvent.Seats == result.Organization.Seats &&
referenceEvent.Storage == result.Organization.MaxStorageGb));
// TODO: add reference events for SmSeats and Service Accounts - see AC-1481
Assert.NotNull(result.Organization); Assert.NotNull(result.Organization);
Assert.NotNull(result.OrganizationUser); Assert.NotNull(result.OrganizationUser);

View File

@ -10,9 +10,6 @@ using Bit.Core.Models.Data;
using Bit.Core.Models.StaticStore; using Bit.Core.Models.StaticStore;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.AutoFixture.Attributes;
@ -65,17 +62,6 @@ public class ProviderClientOrganizationSignUpCommandTests
) )
); );
await sutProvider.GetDependency<IReferenceEventService>()
.Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(referenceEvent =>
referenceEvent.Type == ReferenceEventType.Signup &&
referenceEvent.PlanName == plan.Name &&
referenceEvent.PlanType == plan.Type &&
referenceEvent.Seats == result.Organization.Seats &&
referenceEvent.Storage == result.Organization.MaxStorageGb &&
referenceEvent.SignupInitiationPath == signup.InitiationPath
));
await sutProvider.GetDependency<ICollectionRepository>() await sutProvider.GetDependency<ICollectionRepository>()
.Received(1) .Received(1)
.CreateAsync( .CreateAsync(

View File

@ -22,15 +22,11 @@ using Bit.Core.Settings;
using Bit.Core.Test.AutoFixture.OrganizationFixtures; using Bit.Core.Test.AutoFixture.OrganizationFixtures;
using Bit.Core.Test.AutoFixture.OrganizationUserFixtures; using Bit.Core.Test.AutoFixture.OrganizationUserFixtures;
using Bit.Core.Tokens; using Bit.Core.Tokens;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.AutoFixture.Attributes;
using Bit.Test.Common.Fakes; using Bit.Test.Common.Fakes;
using NSubstitute; using NSubstitute;
using NSubstitute.ExceptionExtensions;
using NSubstitute.ReturnsExtensions; using NSubstitute.ReturnsExtensions;
using Xunit; using Xunit;
using Organization = Bit.Core.AdminConsole.Entities.Organization; using Organization = Bit.Core.AdminConsole.Entities.Organization;
@ -100,10 +96,6 @@ public class OrganizationServiceTests
await sutProvider.GetDependency<IEventService>().Received(1) await sutProvider.GetDependency<IEventService>().Received(1)
.LogOrganizationUserEventsAsync(Arg.Is<IEnumerable<(OrganizationUser, EventType, EventSystemUser, DateTime?)>>(events => .LogOrganizationUserEventsAsync(Arg.Is<IEnumerable<(OrganizationUser, EventType, EventSystemUser, DateTime?)>>(events =>
events.Count() == expectedNewUsersCount)); events.Count() == expectedNewUsersCount));
await sutProvider.GetDependency<IReferenceEventService>().Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(referenceEvent =>
referenceEvent.Type == ReferenceEventType.InvitedUsers && referenceEvent.Id == org.Id &&
referenceEvent.Users == expectedNewUsersCount));
} }
[Theory, PaidOrganizationCustomize, BitAutoData] [Theory, PaidOrganizationCustomize, BitAutoData]
@ -170,10 +162,6 @@ public class OrganizationServiceTests
await sutProvider.GetDependency<IEventService>().Received(1) await sutProvider.GetDependency<IEventService>().Received(1)
.LogOrganizationUserEventsAsync(Arg.Is<IEnumerable<(OrganizationUser, EventType, EventSystemUser, DateTime?)>>(events => .LogOrganizationUserEventsAsync(Arg.Is<IEnumerable<(OrganizationUser, EventType, EventSystemUser, DateTime?)>>(events =>
events.Count(e => e.Item2 == EventType.OrganizationUser_Invited) == expectedNewUsersCount)); events.Count(e => e.Item2 == EventType.OrganizationUser_Invited) == expectedNewUsersCount));
await sutProvider.GetDependency<IReferenceEventService>().Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(referenceEvent =>
referenceEvent.Type == ReferenceEventType.InvitedUsers && referenceEvent.Id == org.Id &&
referenceEvent.Users == expectedNewUsersCount));
} }
[Theory] [Theory]
@ -728,10 +716,6 @@ public class OrganizationServiceTests
.UpdateSubscriptionAsync(Arg.Any<SecretsManagerSubscriptionUpdate>()) .UpdateSubscriptionAsync(Arg.Any<SecretsManagerSubscriptionUpdate>())
.ReturnsForAnyArgs(Task.FromResult(0)).AndDoes(x => organization.SmSeats += invitedSmUsers); .ReturnsForAnyArgs(Task.FromResult(0)).AndDoes(x => organization.SmSeats += invitedSmUsers);
// Throw error at the end of the try block
sutProvider.GetDependency<IReferenceEventService>().RaiseEventAsync(default)
.ThrowsForAnyArgs<BadRequestException>();
sutProvider.GetDependency<IPricingClient>().GetPlanOrThrow(organization.PlanType) sutProvider.GetDependency<IPricingClient>().GetPlanOrThrow(organization.PlanType)
.Returns(StaticStore.GetPlan(organization.PlanType)); .Returns(StaticStore.GetPlan(organization.PlanType));

View File

@ -14,9 +14,6 @@ using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tokens; using Bit.Core.Tokens;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.AutoFixture.Attributes;
@ -57,10 +54,6 @@ public class RegisterUserCommandTests
await sutProvider.GetDependency<IMailService>() await sutProvider.GetDependency<IMailService>()
.Received(1) .Received(1)
.SendWelcomeEmailAsync(user); .SendWelcomeEmailAsync(user);
await sutProvider.GetDependency<IReferenceEventService>()
.Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(refEvent => refEvent.Type == ReferenceEventType.Signup));
} }
[Theory] [Theory]
@ -85,10 +78,6 @@ public class RegisterUserCommandTests
await sutProvider.GetDependency<IMailService>() await sutProvider.GetDependency<IMailService>()
.DidNotReceive() .DidNotReceive()
.SendWelcomeEmailAsync(Arg.Any<User>()); .SendWelcomeEmailAsync(Arg.Any<User>());
await sutProvider.GetDependency<IReferenceEventService>()
.DidNotReceive()
.RaiseEventAsync(Arg.Any<ReferenceEvent>());
} }
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
@ -117,10 +106,6 @@ public class RegisterUserCommandTests
await sutProvider.GetDependency<IUserService>() await sutProvider.GetDependency<IUserService>()
.Received(1) .Received(1)
.CreateUserAsync(user, masterPasswordHash); .CreateUserAsync(user, masterPasswordHash);
await sutProvider.GetDependency<IReferenceEventService>()
.Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(refEvent => refEvent.Type == ReferenceEventType.Signup));
} }
// Complex happy path test // Complex happy path test
@ -215,18 +200,9 @@ public class RegisterUserCommandTests
.Received(1) .Received(1)
.SendWelcomeEmailAsync(user); .SendWelcomeEmailAsync(user);
} }
await sutProvider.GetDependency<IReferenceEventService>()
.Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(refEvent => refEvent.Type == ReferenceEventType.Signup && refEvent.SignupInitiationPath == initiationPath));
} }
else else
{ {
await sutProvider.GetDependency<IReferenceEventService>()
.Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(refEvent => refEvent.Type == ReferenceEventType.Signup && refEvent.SignupInitiationPath == default));
// Even if user doesn't have reference data, we should send them welcome email // Even if user doesn't have reference data, we should send them welcome email
await sutProvider.GetDependency<IMailService>() await sutProvider.GetDependency<IMailService>()
.Received(1) .Received(1)
@ -359,10 +335,6 @@ public class RegisterUserCommandTests
await sutProvider.GetDependency<IMailService>() await sutProvider.GetDependency<IMailService>()
.Received(1) .Received(1)
.SendWelcomeEmailAsync(user); .SendWelcomeEmailAsync(user);
await sutProvider.GetDependency<IReferenceEventService>()
.Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(refEvent => refEvent.Type == ReferenceEventType.Signup && refEvent.ReceiveMarketingEmails == receiveMarketingMaterials));
} }
[Theory] [Theory]
@ -429,10 +401,6 @@ public class RegisterUserCommandTests
await sutProvider.GetDependency<IMailService>() await sutProvider.GetDependency<IMailService>()
.Received(1) .Received(1)
.SendWelcomeEmailAsync(user); .SendWelcomeEmailAsync(user);
await sutProvider.GetDependency<IReferenceEventService>()
.Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(refEvent => refEvent.Type == ReferenceEventType.Signup));
} }
[Theory] [Theory]
@ -506,10 +474,6 @@ public class RegisterUserCommandTests
await sutProvider.GetDependency<IMailService>() await sutProvider.GetDependency<IMailService>()
.Received(1) .Received(1)
.SendWelcomeEmailAsync(user); .SendWelcomeEmailAsync(user);
await sutProvider.GetDependency<IReferenceEventService>()
.Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(refEvent => refEvent.Type == ReferenceEventType.Signup));
} }
[Theory] [Theory]
@ -604,10 +568,6 @@ public class RegisterUserCommandTests
await sutProvider.GetDependency<IMailService>() await sutProvider.GetDependency<IMailService>()
.Received(1) .Received(1)
.SendWelcomeEmailAsync(user); .SendWelcomeEmailAsync(user);
await sutProvider.GetDependency<IReferenceEventService>()
.Received(1)
.RaiseEventAsync(Arg.Is<ReferenceEvent>(refEvent => refEvent.Type == ReferenceEventType.Signup));
} }
[Theory] [Theory]

View File

@ -26,7 +26,6 @@ using Bit.Core.Platform.Push;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tools.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Core.Vault.Repositories; using Bit.Core.Vault.Repositories;
using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture;
@ -316,7 +315,6 @@ public class UserServiceTests
sutProvider.GetDependency<IPaymentService>(), sutProvider.GetDependency<IPaymentService>(),
sutProvider.GetDependency<IPolicyRepository>(), sutProvider.GetDependency<IPolicyRepository>(),
sutProvider.GetDependency<IPolicyService>(), sutProvider.GetDependency<IPolicyService>(),
sutProvider.GetDependency<IReferenceEventService>(),
sutProvider.GetDependency<IFido2>(), sutProvider.GetDependency<IFido2>(),
sutProvider.GetDependency<ICurrentContext>(), sutProvider.GetDependency<ICurrentContext>(),
sutProvider.GetDependency<IGlobalSettings>(), sutProvider.GetDependency<IGlobalSettings>(),
@ -910,7 +908,6 @@ public class UserServiceTests
sutProvider.GetDependency<IPaymentService>(), sutProvider.GetDependency<IPaymentService>(),
sutProvider.GetDependency<IPolicyRepository>(), sutProvider.GetDependency<IPolicyRepository>(),
sutProvider.GetDependency<IPolicyService>(), sutProvider.GetDependency<IPolicyService>(),
sutProvider.GetDependency<IReferenceEventService>(),
sutProvider.GetDependency<IFido2>(), sutProvider.GetDependency<IFido2>(),
sutProvider.GetDependency<ICurrentContext>(), sutProvider.GetDependency<ICurrentContext>(),
sutProvider.GetDependency<IGlobalSettings>(), sutProvider.GetDependency<IGlobalSettings>(),

View File

@ -9,10 +9,7 @@ using Bit.Core.Platform.Push;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Test.AutoFixture.CipherFixtures; using Bit.Core.Test.AutoFixture.CipherFixtures;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.ImportFeatures; using Bit.Core.Tools.ImportFeatures;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Core.Vault.Entities; using Bit.Core.Vault.Entities;
using Bit.Core.Vault.Models.Data; using Bit.Core.Vault.Models.Data;
using Bit.Core.Vault.Repositories; using Bit.Core.Vault.Repositories;
@ -183,8 +180,6 @@ public class ImportCiphersAsyncCommandTests
!cus.Any(cu => cu.CollectionId == collections[0].Id) && // Check that access was not added for the collection that already existed in the organization !cus.Any(cu => cu.CollectionId == collections[0].Id) && // Check that access was not added for the collection that already existed in the organization
cus.All(cu => cu.OrganizationUserId == importingOrganizationUser.Id && cu.Manage == true))); cus.All(cu => cu.OrganizationUserId == importingOrganizationUser.Id && cu.Manage == true)));
await sutProvider.GetDependency<IPushNotificationService>().Received(1).PushSyncVaultAsync(importingUserId); await sutProvider.GetDependency<IPushNotificationService>().Received(1).PushSyncVaultAsync(importingUserId);
await sutProvider.GetDependency<IReferenceEventService>().Received(1).RaiseEventAsync(
Arg.Is<ReferenceEvent>(e => e.Type == ReferenceEventType.VaultImported));
} }
[Theory, BitAutoData] [Theory, BitAutoData]

View File

@ -8,7 +8,6 @@ using Bit.Core.Test.AutoFixture.CurrentContextFixtures;
using Bit.Core.Test.Tools.AutoFixture.SendFixtures; using Bit.Core.Test.Tools.AutoFixture.SendFixtures;
using Bit.Core.Tools.Entities; using Bit.Core.Tools.Entities;
using Bit.Core.Tools.Enums; using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Models.Data; using Bit.Core.Tools.Models.Data;
using Bit.Core.Tools.Repositories; using Bit.Core.Tools.Repositories;
using Bit.Core.Tools.SendFeatures; using Bit.Core.Tools.SendFeatures;
@ -32,7 +31,6 @@ public class NonAnonymousSendCommandTests
private readonly ISendAuthorizationService _sendAuthorizationService; private readonly ISendAuthorizationService _sendAuthorizationService;
private readonly ISendValidationService _sendValidationService; private readonly ISendValidationService _sendValidationService;
private readonly IFeatureService _featureService; private readonly IFeatureService _featureService;
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext; private readonly ICurrentContext _currentContext;
private readonly ISendCoreHelperService _sendCoreHelperService; private readonly ISendCoreHelperService _sendCoreHelperService;
private readonly NonAnonymousSendCommand _nonAnonymousSendCommand; private readonly NonAnonymousSendCommand _nonAnonymousSendCommand;
@ -45,7 +43,6 @@ public class NonAnonymousSendCommandTests
_sendAuthorizationService = Substitute.For<ISendAuthorizationService>(); _sendAuthorizationService = Substitute.For<ISendAuthorizationService>();
_featureService = Substitute.For<IFeatureService>(); _featureService = Substitute.For<IFeatureService>();
_sendValidationService = Substitute.For<ISendValidationService>(); _sendValidationService = Substitute.For<ISendValidationService>();
_referenceEventService = Substitute.For<IReferenceEventService>();
_currentContext = Substitute.For<ICurrentContext>(); _currentContext = Substitute.For<ICurrentContext>();
_sendCoreHelperService = Substitute.For<ISendCoreHelperService>(); _sendCoreHelperService = Substitute.For<ISendCoreHelperService>();
@ -55,8 +52,6 @@ public class NonAnonymousSendCommandTests
_pushNotificationService, _pushNotificationService,
_sendAuthorizationService, _sendAuthorizationService,
_sendValidationService, _sendValidationService,
_referenceEventService,
_currentContext,
_sendCoreHelperService _sendCoreHelperService
); );
} }
@ -135,14 +130,6 @@ public class NonAnonymousSendCommandTests
// For new Sends // For new Sends
await _sendRepository.Received(1).CreateAsync(send); await _sendRepository.Received(1).CreateAsync(send);
await _pushNotificationService.Received(1).PushSyncSendCreateAsync(send); await _pushNotificationService.Received(1).PushSyncSendCreateAsync(send);
await _referenceEventService.Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(e =>
e.Id == userId &&
e.Type == ReferenceEventType.SendCreated &&
e.Source == ReferenceEventSource.User &&
e.SendType == send.Type &&
e.SendHasNotes == true &&
e.ClientId == "test-client" &&
e.ClientVersion == Version.Parse("1.0.0")));
} }
else else
{ {
@ -150,7 +137,6 @@ public class NonAnonymousSendCommandTests
await _sendRepository.Received(1).UpsertAsync(send); await _sendRepository.Received(1).UpsertAsync(send);
Assert.NotEqual(initialDate, send.RevisionDate); Assert.NotEqual(initialDate, send.RevisionDate);
await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send); await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send);
await _referenceEventService.DidNotReceive().RaiseEventAsync(Arg.Any<ReferenceEvent>());
} }
} }
@ -234,14 +220,6 @@ public class NonAnonymousSendCommandTests
// For new Sends // For new Sends
await _sendRepository.Received(1).CreateAsync(send); await _sendRepository.Received(1).CreateAsync(send);
await _pushNotificationService.Received(1).PushSyncSendCreateAsync(send); await _pushNotificationService.Received(1).PushSyncSendCreateAsync(send);
await _referenceEventService.Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(e =>
e.Id == userId &&
e.Type == ReferenceEventType.SendCreated &&
e.Source == ReferenceEventSource.User &&
e.SendType == send.Type &&
e.HasPassword == false &&
e.ClientId == "test-client" &&
e.ClientVersion == Version.Parse("1.0.0")));
} }
else else
{ {
@ -249,7 +227,6 @@ public class NonAnonymousSendCommandTests
await _sendRepository.Received(1).UpsertAsync(send); await _sendRepository.Received(1).UpsertAsync(send);
Assert.NotEqual(initialDate, send.RevisionDate); Assert.NotEqual(initialDate, send.RevisionDate);
await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send); await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send);
await _referenceEventService.DidNotReceive().RaiseEventAsync(Arg.Any<ReferenceEvent>());
} }
} }
@ -285,7 +262,6 @@ public class NonAnonymousSendCommandTests
await _sendRepository.DidNotReceive().UpsertAsync(Arg.Any<Send>()); await _sendRepository.DidNotReceive().UpsertAsync(Arg.Any<Send>());
await _pushNotificationService.DidNotReceive().PushSyncSendCreateAsync(Arg.Any<Send>()); await _pushNotificationService.DidNotReceive().PushSyncSendCreateAsync(Arg.Any<Send>());
await _pushNotificationService.DidNotReceive().PushSyncSendUpdateAsync(Arg.Any<Send>()); await _pushNotificationService.DidNotReceive().PushSyncSendUpdateAsync(Arg.Any<Send>());
await _referenceEventService.DidNotReceive().RaiseEventAsync(Arg.Any<ReferenceEvent>());
} }
[Theory] [Theory]
@ -328,14 +304,6 @@ public class NonAnonymousSendCommandTests
// For new Sends // For new Sends
await _sendRepository.Received(1).CreateAsync(send); await _sendRepository.Received(1).CreateAsync(send);
await _pushNotificationService.Received(1).PushSyncSendCreateAsync(send); await _pushNotificationService.Received(1).PushSyncSendCreateAsync(send);
await _referenceEventService.Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(e =>
e.Id == userId &&
e.Type == ReferenceEventType.SendCreated &&
e.Source == ReferenceEventSource.User &&
e.SendType == send.Type &&
e.SendHasNotes == true &&
e.ClientId == "test-client" &&
e.ClientVersion == Version.Parse("1.0.0")));
} }
else else
{ {
@ -343,7 +311,6 @@ public class NonAnonymousSendCommandTests
await _sendRepository.Received(1).UpsertAsync(send); await _sendRepository.Received(1).UpsertAsync(send);
Assert.NotEqual(initialDate, send.RevisionDate); Assert.NotEqual(initialDate, send.RevisionDate);
await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send); await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send);
await _referenceEventService.DidNotReceive().RaiseEventAsync(Arg.Any<ReferenceEvent>());
} }
} }
@ -386,9 +353,6 @@ public class NonAnonymousSendCommandTests
// Verify push notification wasn't sent // Verify push notification wasn't sent
await _pushNotificationService.DidNotReceive().PushSyncSendCreateAsync(Arg.Any<Send>()); await _pushNotificationService.DidNotReceive().PushSyncSendCreateAsync(Arg.Any<Send>());
await _pushNotificationService.DidNotReceive().PushSyncSendUpdateAsync(Arg.Any<Send>()); await _pushNotificationService.DidNotReceive().PushSyncSendUpdateAsync(Arg.Any<Send>());
// Verify reference event service wasn't called
await _referenceEventService.DidNotReceive().RaiseEventAsync(Arg.Any<ReferenceEvent>());
} }
[Theory] [Theory]
@ -431,13 +395,6 @@ public class NonAnonymousSendCommandTests
// For new Sends // For new Sends
await _sendRepository.Received(1).CreateAsync(send); await _sendRepository.Received(1).CreateAsync(send);
await _pushNotificationService.Received(1).PushSyncSendCreateAsync(send); await _pushNotificationService.Received(1).PushSyncSendCreateAsync(send);
await _referenceEventService.Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(e =>
e.Id == userId &&
e.Type == ReferenceEventType.SendCreated &&
e.Source == ReferenceEventSource.User &&
e.SendType == send.Type &&
e.ClientId == "test-client" &&
e.ClientVersion == Version.Parse("1.0.0")));
} }
else else
{ {
@ -445,7 +402,6 @@ public class NonAnonymousSendCommandTests
await _sendRepository.Received(1).UpsertAsync(send); await _sendRepository.Received(1).UpsertAsync(send);
Assert.NotEqual(initialDate, send.RevisionDate); Assert.NotEqual(initialDate, send.RevisionDate);
await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send); await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send);
await _referenceEventService.DidNotReceive().RaiseEventAsync(Arg.Any<ReferenceEvent>());
} }
} }
@ -481,9 +437,6 @@ public class NonAnonymousSendCommandTests
// Verify push notification was sent for the update // Verify push notification was sent for the update
await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send); await _pushNotificationService.Received(1).PushSyncSendUpdateAsync(send);
// Verify no reference event was raised (only happens for new sends)
await _referenceEventService.DidNotReceive().RaiseEventAsync(Arg.Any<ReferenceEvent>());
} }
[Fact] [Fact]

View File

@ -1,5 +1,4 @@
using Bit.Core.Context; using Bit.Core.Platform.Push;
using Bit.Core.Platform.Push;
using Bit.Core.Tools.Entities; using Bit.Core.Tools.Entities;
using Bit.Core.Tools.Models.Data; using Bit.Core.Tools.Models.Data;
using Bit.Core.Tools.Repositories; using Bit.Core.Tools.Repositories;
@ -15,8 +14,6 @@ public class SendAuthorizationServiceTests
private readonly ISendRepository _sendRepository; private readonly ISendRepository _sendRepository;
private readonly IPasswordHasher<Bit.Core.Entities.User> _passwordHasher; private readonly IPasswordHasher<Bit.Core.Entities.User> _passwordHasher;
private readonly IPushNotificationService _pushNotificationService; private readonly IPushNotificationService _pushNotificationService;
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext;
private readonly SendAuthorizationService _sendAuthorizationService; private readonly SendAuthorizationService _sendAuthorizationService;
public SendAuthorizationServiceTests() public SendAuthorizationServiceTests()
@ -24,15 +21,11 @@ public class SendAuthorizationServiceTests
_sendRepository = Substitute.For<ISendRepository>(); _sendRepository = Substitute.For<ISendRepository>();
_passwordHasher = Substitute.For<IPasswordHasher<Bit.Core.Entities.User>>(); _passwordHasher = Substitute.For<IPasswordHasher<Bit.Core.Entities.User>>();
_pushNotificationService = Substitute.For<IPushNotificationService>(); _pushNotificationService = Substitute.For<IPushNotificationService>();
_referenceEventService = Substitute.For<IReferenceEventService>();
_currentContext = Substitute.For<ICurrentContext>();
_sendAuthorizationService = new SendAuthorizationService( _sendAuthorizationService = new SendAuthorizationService(
_sendRepository, _sendRepository,
_passwordHasher, _passwordHasher,
_pushNotificationService, _pushNotificationService);
_referenceEventService,
_currentContext);
} }

View File

@ -14,9 +14,6 @@ using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tokens; using Bit.Core.Tokens;
using Bit.Core.Tools.Enums;
using Bit.Core.Tools.Models.Business;
using Bit.Core.Tools.Services;
using Bit.Identity.Controllers; using Bit.Identity.Controllers;
using Bit.Identity.Models.Request.Accounts; using Bit.Identity.Models.Request.Accounts;
using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.AutoFixture.Attributes;
@ -40,7 +37,6 @@ public class AccountsControllerTests : IDisposable
private readonly IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable> _assertionOptionsDataProtector; private readonly IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable> _assertionOptionsDataProtector;
private readonly IGetWebAuthnLoginCredentialAssertionOptionsCommand _getWebAuthnLoginCredentialAssertionOptionsCommand; private readonly IGetWebAuthnLoginCredentialAssertionOptionsCommand _getWebAuthnLoginCredentialAssertionOptionsCommand;
private readonly ISendVerificationEmailForRegistrationCommand _sendVerificationEmailForRegistrationCommand; private readonly ISendVerificationEmailForRegistrationCommand _sendVerificationEmailForRegistrationCommand;
private readonly IReferenceEventService _referenceEventService;
private readonly IFeatureService _featureService; private readonly IFeatureService _featureService;
private readonly IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> _registrationEmailVerificationTokenDataFactory; private readonly IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> _registrationEmailVerificationTokenDataFactory;
private readonly GlobalSettings _globalSettings; private readonly GlobalSettings _globalSettings;
@ -55,7 +51,6 @@ public class AccountsControllerTests : IDisposable
_assertionOptionsDataProtector = Substitute.For<IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable>>(); _assertionOptionsDataProtector = Substitute.For<IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable>>();
_getWebAuthnLoginCredentialAssertionOptionsCommand = Substitute.For<IGetWebAuthnLoginCredentialAssertionOptionsCommand>(); _getWebAuthnLoginCredentialAssertionOptionsCommand = Substitute.For<IGetWebAuthnLoginCredentialAssertionOptionsCommand>();
_sendVerificationEmailForRegistrationCommand = Substitute.For<ISendVerificationEmailForRegistrationCommand>(); _sendVerificationEmailForRegistrationCommand = Substitute.For<ISendVerificationEmailForRegistrationCommand>();
_referenceEventService = Substitute.For<IReferenceEventService>();
_featureService = Substitute.For<IFeatureService>(); _featureService = Substitute.For<IFeatureService>();
_registrationEmailVerificationTokenDataFactory = Substitute.For<IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable>>(); _registrationEmailVerificationTokenDataFactory = Substitute.For<IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable>>();
_globalSettings = Substitute.For<GlobalSettings>(); _globalSettings = Substitute.For<GlobalSettings>();
@ -68,7 +63,6 @@ public class AccountsControllerTests : IDisposable
_assertionOptionsDataProtector, _assertionOptionsDataProtector,
_getWebAuthnLoginCredentialAssertionOptionsCommand, _getWebAuthnLoginCredentialAssertionOptionsCommand,
_sendVerificationEmailForRegistrationCommand, _sendVerificationEmailForRegistrationCommand,
_referenceEventService,
_featureService, _featureService,
_registrationEmailVerificationTokenDataFactory, _registrationEmailVerificationTokenDataFactory,
_globalSettings _globalSettings
@ -163,8 +157,6 @@ public class AccountsControllerTests : IDisposable
var okResult = Assert.IsType<OkObjectResult>(result); var okResult = Assert.IsType<OkObjectResult>(result);
Assert.Equal(200, okResult.StatusCode); Assert.Equal(200, okResult.StatusCode);
Assert.Equal(token, okResult.Value); Assert.Equal(token, okResult.Value);
await _referenceEventService.Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(e => e.Type == ReferenceEventType.SignupEmailSubmit));
} }
[Theory] [Theory]
@ -187,7 +179,6 @@ public class AccountsControllerTests : IDisposable
// Assert // Assert
var noContentResult = Assert.IsType<NoContentResult>(result); var noContentResult = Assert.IsType<NoContentResult>(result);
Assert.Equal(204, noContentResult.StatusCode); Assert.Equal(204, noContentResult.StatusCode);
await _referenceEventService.Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(e => e.Type == ReferenceEventType.SignupEmailSubmit));
} }
[Theory, BitAutoData] [Theory, BitAutoData]
@ -404,12 +395,6 @@ public class AccountsControllerTests : IDisposable
// Assert // Assert
var okResult = Assert.IsType<OkResult>(result); var okResult = Assert.IsType<OkResult>(result);
Assert.Equal(200, okResult.StatusCode); Assert.Equal(200, okResult.StatusCode);
await _referenceEventService.Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(e =>
e.Type == ReferenceEventType.SignupEmailClicked
&& e.EmailVerificationTokenValid == true
&& e.UserAlreadyExists == false
));
} }
[Theory, BitAutoData] [Theory, BitAutoData]
@ -435,12 +420,6 @@ public class AccountsControllerTests : IDisposable
// Act & assert // Act & assert
await Assert.ThrowsAsync<BadRequestException>(() => _sut.PostRegisterVerificationEmailClicked(requestModel)); await Assert.ThrowsAsync<BadRequestException>(() => _sut.PostRegisterVerificationEmailClicked(requestModel));
await _referenceEventService.Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(e =>
e.Type == ReferenceEventType.SignupEmailClicked
&& e.EmailVerificationTokenValid == false
&& e.UserAlreadyExists == false
));
} }
@ -467,12 +446,6 @@ public class AccountsControllerTests : IDisposable
// Act & assert // Act & assert
await Assert.ThrowsAsync<BadRequestException>(() => _sut.PostRegisterVerificationEmailClicked(requestModel)); await Assert.ThrowsAsync<BadRequestException>(() => _sut.PostRegisterVerificationEmailClicked(requestModel));
await _referenceEventService.Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(e =>
e.Type == ReferenceEventType.SignupEmailClicked
&& e.EmailVerificationTokenValid == true
&& e.UserAlreadyExists == true
));
} }
private void SetDefaultKdfHmacKey(byte[]? newKey) private void SetDefaultKdfHmacKey(byte[]? newKey)

View File

@ -4,7 +4,6 @@ using Bit.Core.Platform.Push;
using Bit.Core.Platform.Push.Internal; using Bit.Core.Platform.Push.Internal;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Tools.Services;
using Bit.Infrastructure.EntityFramework.Repositories; using Bit.Infrastructure.EntityFramework.Repositories;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.Mvc.Testing;
@ -209,9 +208,6 @@ public abstract class WebApplicationFactoryBase<T> : WebApplicationFactory<T>
// TODO: Install and use azurite in CI pipeline // TODO: Install and use azurite in CI pipeline
Replace<IInstallationDeviceRepository, NoopRepos.InstallationDeviceRepository>(services); Replace<IInstallationDeviceRepository, NoopRepos.InstallationDeviceRepository>(services);
// TODO: Install and use azurite in CI pipeline
Replace<IReferenceEventService, NoopReferenceEventService>(services);
// Our Rate limiter works so well that it begins to fail tests unless we carve out // Our Rate limiter works so well that it begins to fail tests unless we carve out
// one whitelisted ip. We should still test the rate limiter though and they should change the Ip // one whitelisted ip. We should still test the rate limiter though and they should change the Ip
// to something that is NOT whitelisted // to something that is NOT whitelisted