1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-25 12:45:18 +01:00

[PM-214] Extend Reference Events (#2926)

* Extend ReferenceEvents

Add ClientId and ClientVersion
Modify all callsites to pass in currentContext if available to fill ClientId and ClientVersion

* Extend ReferenceEvent to save if Send has notes
This commit is contained in:
Daniel James Smith 2023-05-16 16:21:57 +02:00 committed by GitHub
parent bfd3f85bb0
commit 12f21b0c33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 57 additions and 31 deletions

View File

@ -2,6 +2,7 @@
using Bit.Admin.Models;
using Bit.Admin.Services;
using Bit.Admin.Utilities;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Models.OrganizationConnectionConfigs;
@ -40,6 +41,7 @@ public class OrganizationsController : Controller
private readonly IProviderRepository _providerRepository;
private readonly ILogger<OrganizationsController> _logger;
private readonly IAccessControlService _accessControlService;
private readonly ICurrentContext _currentContext;
public OrganizationsController(
IOrganizationService organizationService,
@ -59,7 +61,8 @@ public class OrganizationsController : Controller
IUserService userService,
IProviderRepository providerRepository,
ILogger<OrganizationsController> logger,
IAccessControlService accessControlService)
IAccessControlService accessControlService,
ICurrentContext currentContext)
{
_organizationService = organizationService;
_organizationRepository = organizationRepository;
@ -79,6 +82,7 @@ public class OrganizationsController : Controller
_providerRepository = providerRepository;
_logger = logger;
_accessControlService = accessControlService;
_currentContext = currentContext;
}
[RequirePermission(Permission.Org_List_View)]
@ -174,7 +178,7 @@ public class OrganizationsController : Controller
await _organizationRepository.ReplaceAsync(organization);
await _applicationCacheService.UpsertOrganizationAbilityAsync(organization);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.OrganizationEditedByAdmin, organization)
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.OrganizationEditedByAdmin, organization, _currentContext)
{
EventRaisedByUser = _userService.GetUserName(User),
SalesAssistedTrialStarted = model.SalesAssistedTrialStarted,

View File

@ -120,7 +120,7 @@ public class SecretsController : Controller
await _eventService.LogServiceAccountSecretEventAsync(userId, secret, EventType.Secret_Retrieved);
var org = await _organizationRepository.GetByIdAsync(secret.OrganizationId);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.SmServiceAccountAccessedSecret, org));
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.SmServiceAccountAccessedSecret, org, _currentContext));
}
return new SecretResponseModel(secret, access.Read, access.Write);

View File

@ -1,4 +1,5 @@
using Bit.Billing.Constants;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
@ -39,6 +40,7 @@ public class StripeController : Controller
private readonly IReferenceEventService _referenceEventService;
private readonly ITaxRateRepository _taxRateRepository;
private readonly IUserRepository _userRepository;
private readonly ICurrentContext _currentContext;
public StripeController(
GlobalSettings globalSettings,
@ -55,7 +57,8 @@ public class StripeController : Controller
IReferenceEventService referenceEventService,
ILogger<StripeController> logger,
ITaxRateRepository taxRateRepository,
IUserRepository userRepository)
IUserRepository userRepository,
ICurrentContext currentContext)
{
_billingSettings = billingSettings?.Value;
_hostingEnvironment = hostingEnvironment;
@ -79,6 +82,7 @@ public class StripeController : Controller
PublicKey = globalSettings.Braintree.PublicKey,
PrivateKey = globalSettings.Braintree.PrivateKey
};
_currentContext = currentContext;
}
[HttpPost("webhook")]
@ -419,7 +423,7 @@ public class StripeController : Controller
var organization = await _organizationRepository.GetByIdAsync(ids.Item1.Value);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.Rebilled, organization)
new ReferenceEvent(ReferenceEventType.Rebilled, organization, _currentContext)
{
PlanName = organization?.Plan,
PlanType = organization?.PlanType,
@ -437,7 +441,7 @@ public class StripeController : Controller
var user = await _userRepository.GetByIdAsync(ids.Item2.Value);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.Rebilled, user)
new ReferenceEvent(ReferenceEventType.Rebilled, user, _currentContext)
{
PlanName = PremiumPlanId,
Storage = user?.MaxStorageGb,

View File

@ -1,4 +1,5 @@
using Bit.Core.Entities;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Data;
@ -17,17 +18,20 @@ public class CreateGroupCommand : ICreateGroupCommand
private readonly IGroupRepository _groupRepository;
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IReferenceEventService _referenceEventService;
private readonly ICurrentContext _currentContext;
public CreateGroupCommand(
IEventService eventService,
IGroupRepository groupRepository,
IOrganizationUserRepository organizationUserRepository,
IReferenceEventService referenceEventService)
IReferenceEventService referenceEventService,
ICurrentContext currentContext)
{
_eventService = eventService;
_groupRepository = groupRepository;
_organizationUserRepository = organizationUserRepository;
_referenceEventService = referenceEventService;
_currentContext = currentContext;
}
public async Task CreateGroupAsync(Group group, Organization organization,
@ -73,7 +77,7 @@ public class CreateGroupCommand : ICreateGroupCommand
await _groupRepository.CreateAsync(group, collections);
}
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.GroupCreated, organization));
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.GroupCreated, organization, _currentContext));
}
private async Task GroupRepositoryUpdateUsersAsync(Group group, IEnumerable<Guid> userIds,

View File

@ -76,7 +76,7 @@ public class CollectionService : ICollectionService
}
await _eventService.LogCollectionEventAsync(collection, Enums.EventType.Collection_Created);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.CollectionCreated, org));
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.CollectionCreated, org, _currentContext));
}
else
{

View File

@ -147,7 +147,7 @@ public class OrganizationService : IOrganizationService
await _paymentService.CancelSubscriptionAsync(organization, eop);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.CancelSubscription, organization)
new ReferenceEvent(ReferenceEventType.CancelSubscription, organization, _currentContext)
{
EndOfPeriod = endOfPeriod,
});
@ -163,7 +163,7 @@ public class OrganizationService : IOrganizationService
await _paymentService.ReinstateSubscriptionAsync(organization);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.ReinstateSubscription, organization));
new ReferenceEvent(ReferenceEventType.ReinstateSubscription, organization, _currentContext));
}
public async Task<Tuple<bool, string>> UpgradePlanAsync(Guid organizationId, OrganizationUpgrade upgrade)
@ -357,7 +357,7 @@ public class OrganizationService : IOrganizationService
if (success)
{
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.UpgradePlan, organization)
new ReferenceEvent(ReferenceEventType.UpgradePlan, organization, _currentContext)
{
PlanName = newPlan.Name,
PlanType = newPlan.Type,
@ -393,7 +393,7 @@ public class OrganizationService : IOrganizationService
var secret = await BillingHelpers.AdjustStorageAsync(_paymentService, organization, storageAdjustmentGb,
plan.StripeStoragePlanId);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.AdjustStorage, organization)
new ReferenceEvent(ReferenceEventType.AdjustStorage, organization, _currentContext)
{
PlanName = plan.Name,
PlanType = plan.Type,
@ -530,7 +530,7 @@ public class OrganizationService : IOrganizationService
var paymentIntentClientSecret = await _paymentService.AdjustSeatsAsync(organization, plan, additionalSeats, prorationDate);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.AdjustSeats, organization)
new ReferenceEvent(ReferenceEventType.AdjustSeats, organization, _currentContext)
{
PlanName = plan.Name,
PlanType = plan.Type,
@ -681,7 +681,7 @@ public class OrganizationService : IOrganizationService
var ownerId = provider ? default : signup.Owner.Id;
var returnValue = await SignUpAsync(organization, ownerId, signup.OwnerKey, signup.CollectionName, true);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.Signup, organization)
new ReferenceEvent(ReferenceEventType.Signup, organization, _currentContext)
{
PlanName = plan.Name,
PlanType = plan.Type,
@ -853,7 +853,7 @@ public class OrganizationService : IOrganizationService
organization.ExpirationDate.Value >= DateTime.UtcNow;
await _paymentService.CancelSubscriptionAsync(organization, eop);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.DeleteAccount, organization));
new ReferenceEvent(ReferenceEventType.DeleteAccount, organization, _currentContext));
}
catch (GatewayException) { }
}
@ -1136,7 +1136,7 @@ public class OrganizationService : IOrganizationService
await SendInvitesAsync(orgUsers.Concat(limitedCollectionOrgUsers.Select(u => u.Item1)), organization);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.InvitedUsers, organization)
new ReferenceEvent(ReferenceEventType.InvitedUsers, organization, _currentContext)
{
Users = orgUserInvitedCount
});
@ -1971,7 +1971,7 @@ public class OrganizationService : IOrganizationService
}
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.DirectorySynced, organization));
new ReferenceEvent(ReferenceEventType.DirectorySynced, organization, _currentContext));
}
public async Task DeleteSsoUserAsync(Guid userId, Guid? organizationId)
@ -2472,7 +2472,7 @@ public class OrganizationService : IOrganizationService
await SendInviteAsync(ownerOrganizationUser, organization, true);
await _eventService.LogOrganizationUserEventAsync(ownerOrganizationUser, EventType.OrganizationUser_Invited);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.OrganizationCreatedByAdmin, organization)
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.OrganizationCreatedByAdmin, organization, _currentContext)
{
EventRaisedByUser = userService.GetUserName(user),
SalesAssistedTrialStarted = salesAssistedTrialStarted,

View File

@ -253,7 +253,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
await _userRepository.DeleteAsync(user);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.DeleteAccount, user));
new ReferenceEvent(ReferenceEventType.DeleteAccount, user, _currentContext));
await _pushService.PushLogOutAsync(user.Id);
return IdentityResult.Success;
}
@ -324,7 +324,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
if (result == IdentityResult.Success)
{
await _mailService.SendWelcomeEmailAsync(user);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user));
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user, _currentContext));
}
return result;
@ -336,7 +336,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
if (result == IdentityResult.Success)
{
await _mailService.SendWelcomeEmailAsync(user);
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user));
await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user, _currentContext));
}
return result;
@ -1049,7 +1049,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
await SaveUserAsync(user);
await _pushService.PushSyncVaultAsync(user.Id);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.UpgradePlan, user)
new ReferenceEvent(ReferenceEventType.UpgradePlan, user, _currentContext)
{
Storage = user.MaxStorageGb,
PlanName = PremiumPlanId,
@ -1138,7 +1138,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
var secret = await BillingHelpers.AdjustStorageAsync(_paymentService, user, storageAdjustmentGb,
StoragePlanId);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.AdjustStorage, user)
new ReferenceEvent(ReferenceEventType.AdjustStorage, user, _currentContext)
{
Storage = storageAdjustmentGb,
PlanName = StoragePlanId,
@ -1171,7 +1171,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
}
await _paymentService.CancelSubscriptionAsync(user, eop, accountDelete);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.CancelSubscription, user)
new ReferenceEvent(ReferenceEventType.CancelSubscription, user, _currentContext)
{
EndOfPeriod = eop,
});
@ -1181,7 +1181,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
{
await _paymentService.ReinstateSubscriptionAsync(user);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.ReinstateSubscription, user));
new ReferenceEvent(ReferenceEventType.ReinstateSubscription, user, _currentContext));
}
public async Task EnablePremiumAsync(Guid userId, DateTime? expirationDate)
@ -1436,7 +1436,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
if (result.Succeeded)
{
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.ConfirmEmailAddress, user));
new ReferenceEvent(ReferenceEventType.ConfirmEmailAddress, user, _currentContext));
}
return result;
}

View File

@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using Bit.Core.Context;
using Bit.Core.Enums;
using Bit.Core.Tools.Entities;
using Bit.Core.Tools.Enums;
@ -9,7 +10,7 @@ public class ReferenceEvent
{
public ReferenceEvent() { }
public ReferenceEvent(ReferenceEventType type, IReferenceable source)
public ReferenceEvent(ReferenceEventType type, IReferenceable source, ICurrentContext currentContext)
{
Type = type;
if (source != null)
@ -18,6 +19,11 @@ public class ReferenceEvent
Id = source.Id;
ReferenceData = source.ReferenceData;
}
if (currentContext != null)
{
ClientId = currentContext.ClientId;
ClientVersion = currentContext.ClientVersion;
}
}
[JsonConverter(typeof(JsonStringEnumConverter))]
@ -52,6 +58,8 @@ public class ReferenceEvent
[JsonConverter(typeof(JsonStringEnumConverter))]
public SendType? SendType { get; set; }
public bool? SendHasNotes { get; set; }
public int? MaxAccessCount { get; set; }
public bool? HasPassword { get; set; }
@ -59,4 +67,7 @@ public class ReferenceEvent
public string EventRaisedByUser { get; set; }
public bool? SalesAssistedTrialStarted { get; set; }
public string ClientId { get; set; }
public Version? ClientVersion { get; set; }
}

View File

@ -270,6 +270,9 @@ public class SendService : ISendService
SendType = send.Type,
MaxAccessCount = send.MaxAccessCount,
HasPassword = !string.IsNullOrWhiteSpace(send.Password),
SendHasNotes = send.Data?.Contains("Notes"),
ClientId = _currentContext.ClientId,
ClientVersion = _currentContext.ClientVersion
});
}

View File

@ -88,7 +88,7 @@ public class CipherService : ICipherService
await _cipherRepository.CreateAsync(cipher, collectionIds);
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.CipherCreated, await _organizationRepository.GetByIdAsync(cipher.OrganizationId.Value)));
new ReferenceEvent(ReferenceEventType.CipherCreated, await _organizationRepository.GetByIdAsync(cipher.OrganizationId.Value), _currentContext));
}
else
{
@ -757,7 +757,7 @@ public class CipherService : ICipherService
if (org != null)
{
await _referenceEventService.RaiseEventAsync(
new ReferenceEvent(ReferenceEventType.VaultImported, org));
new ReferenceEvent(ReferenceEventType.VaultImported, org, _currentContext));
}
}