using Azure; using Azure.Data.Tables; using Bit.Core.Enums; using Bit.Core.Utilities; namespace Bit.Core.Models.Data; // used solely for interaction with Azure Table Storage public class AzureEvent : ITableEntity { public string PartitionKey { get; set; } public string RowKey { get; set; } public DateTimeOffset? Timestamp { get; set; } public ETag ETag { get; set; } public DateTime Date { get; set; } public int Type { get; set; } public Guid? UserId { get; set; } public Guid? OrganizationId { get; set; } public Guid? InstallationId { get; set; } public Guid? ProviderId { get; set; } public Guid? CipherId { get; set; } public Guid? CollectionId { get; set; } public Guid? PolicyId { get; set; } public Guid? GroupId { get; set; } public Guid? OrganizationUserId { get; set; } public Guid? ProviderUserId { get; set; } public Guid? ProviderOrganizationId { get; set; } public int? DeviceType { get; set; } public string IpAddress { get; set; } public Guid? ActingUserId { get; set; } public int? SystemUser { get; set; } public string DomainName { get; set; } public Guid? SecretId { get; set; } public Guid? ServiceAccountId { get; set; } public EventTableEntity ToEventTableEntity() { return new EventTableEntity { PartitionKey = PartitionKey, RowKey = RowKey, Timestamp = Timestamp, ETag = ETag, Date = Date, Type = (EventType)Type, UserId = UserId, OrganizationId = OrganizationId, InstallationId = InstallationId, ProviderId = ProviderId, CipherId = CipherId, CollectionId = CollectionId, PolicyId = PolicyId, GroupId = GroupId, OrganizationUserId = OrganizationUserId, ProviderUserId = ProviderUserId, ProviderOrganizationId = ProviderOrganizationId, DeviceType = DeviceType.HasValue ? (DeviceType)DeviceType.Value : null, IpAddress = IpAddress, ActingUserId = ActingUserId, SystemUser = SystemUser.HasValue ? (EventSystemUser)SystemUser.Value : null, DomainName = DomainName, SecretId = SecretId, ServiceAccountId = ServiceAccountId }; } } public class EventTableEntity : IEvent { public EventTableEntity() { } private EventTableEntity(IEvent e) { Date = e.Date; Type = e.Type; UserId = e.UserId; OrganizationId = e.OrganizationId; InstallationId = e.InstallationId; ProviderId = e.ProviderId; CipherId = e.CipherId; CollectionId = e.CollectionId; PolicyId = e.PolicyId; GroupId = e.GroupId; OrganizationUserId = e.OrganizationUserId; ProviderUserId = e.ProviderUserId; ProviderOrganizationId = e.ProviderOrganizationId; DeviceType = e.DeviceType; IpAddress = e.IpAddress; ActingUserId = e.ActingUserId; SystemUser = e.SystemUser; DomainName = e.DomainName; SecretId = e.SecretId; ServiceAccountId = e.ServiceAccountId; } public string PartitionKey { get; set; } public string RowKey { get; set; } public DateTimeOffset? Timestamp { get; set; } public ETag ETag { get; set; } public DateTime Date { get; set; } public EventType Type { get; set; } public Guid? UserId { get; set; } public Guid? OrganizationId { get; set; } public Guid? InstallationId { get; set; } public Guid? ProviderId { get; set; } public Guid? CipherId { get; set; } public Guid? CollectionId { get; set; } public Guid? PolicyId { get; set; } public Guid? GroupId { get; set; } public Guid? OrganizationUserId { get; set; } public Guid? ProviderUserId { get; set; } public Guid? ProviderOrganizationId { get; set; } public DeviceType? DeviceType { get; set; } public string IpAddress { get; set; } public Guid? ActingUserId { get; set; } public EventSystemUser? SystemUser { get; set; } public string DomainName { get; set; } public Guid? SecretId { get; set; } public Guid? ServiceAccountId { get; set; } public AzureEvent ToAzureEvent() { return new AzureEvent { PartitionKey = PartitionKey, RowKey = RowKey, Timestamp = Timestamp, ETag = ETag, Date = Date, Type = (int)Type, UserId = UserId, OrganizationId = OrganizationId, InstallationId = InstallationId, ProviderId = ProviderId, CipherId = CipherId, CollectionId = CollectionId, PolicyId = PolicyId, GroupId = GroupId, OrganizationUserId = OrganizationUserId, ProviderUserId = ProviderUserId, ProviderOrganizationId = ProviderOrganizationId, DeviceType = DeviceType.HasValue ? (int)DeviceType.Value : null, IpAddress = IpAddress, ActingUserId = ActingUserId, SystemUser = SystemUser.HasValue ? (int)SystemUser.Value : null, DomainName = DomainName, SecretId = SecretId, ServiceAccountId = ServiceAccountId }; } public static List IndexEvent(EventMessage e) { var uniquifier = e.IdempotencyId.GetValueOrDefault(Guid.NewGuid()); var pKey = GetPartitionKey(e); var dateKey = CoreHelpers.DateTimeToTableStorageKey(e.Date); var entities = new List { new EventTableEntity(e) { PartitionKey = pKey, RowKey = $"Date={dateKey}__Uniquifier={uniquifier}" } }; if (e.OrganizationId.HasValue && e.ActingUserId.HasValue) { entities.Add(new EventTableEntity(e) { PartitionKey = pKey, RowKey = $"ActingUserId={e.ActingUserId}__Date={dateKey}__Uniquifier={uniquifier}" }); } if (!e.OrganizationId.HasValue && e.ProviderId.HasValue && e.ActingUserId.HasValue) { entities.Add(new EventTableEntity(e) { PartitionKey = pKey, RowKey = $"ActingUserId={e.ActingUserId}__Date={dateKey}__Uniquifier={uniquifier}" }); } if (e.CipherId.HasValue) { entities.Add(new EventTableEntity(e) { PartitionKey = pKey, RowKey = $"CipherId={e.CipherId}__Date={dateKey}__Uniquifier={uniquifier}" }); } if (e.OrganizationId.HasValue && e.ServiceAccountId.HasValue) { entities.Add(new EventTableEntity(e) { PartitionKey = pKey, RowKey = $"ServiceAccountId={e.ServiceAccountId}__Date={dateKey}__Uniquifier={uniquifier}" }); } if (e.SecretId.HasValue) { entities.Add(new EventTableEntity(e) { PartitionKey = pKey, RowKey = $"SecretId={e.CipherId}__Date={dateKey}__Uniquifier={uniquifier}" }); } return entities; } private static string GetPartitionKey(EventMessage e) { if (e.OrganizationId.HasValue) { return $"OrganizationId={e.OrganizationId}"; } if (e.ProviderId.HasValue) { return $"ProviderId={e.ProviderId}"; } return $"UserId={e.UserId}"; } }