Browse Source

SM-1487-AddingBulkEvents

SM-1301-get-by-id-changes-events
cd-bitwarden 6 months ago
parent
commit
acc89a88e9
  1. 6
      src/Api/AdminConsole/Models/Response/EventResponseModel.cs
  2. 7
      src/Api/AdminConsole/Public/Models/Response/EventResponseModel.cs
  3. 4
      src/Api/SecretsManager/Controllers/SecretsController.cs
  4. 2
      src/Core/AdminConsole/Entities/Event.cs
  5. 2
      src/Core/AdminConsole/Enums/EventType.cs
  6. 19
      src/Core/AdminConsole/Models/Data/EventMessage.cs
  7. 18
      src/Core/AdminConsole/Models/Data/EventTableEntity.cs
  8. 1
      src/Core/AdminConsole/Models/Data/IEvent.cs
  9. 111
      src/Core/AdminConsole/Services/Implementations/EventService.cs

6
src/Api/AdminConsole/Models/Response/EventResponseModel.cs

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
using Bit.Core.Enums;
#nullable enable
using Bit.Core.Enums;
using Bit.Core.Models.Api;
using Bit.Core.Models.Data;
@ -34,6 +36,7 @@ public class EventResponseModel : ResponseModel @@ -34,6 +36,7 @@ public class EventResponseModel : ResponseModel
DomainName = ev.DomainName;
SecretId = ev.SecretId;
ServiceAccountId = ev.ServiceAccountId;
SecretIds = ev.SecretIds;
}
public EventType Type { get; set; }
@ -56,4 +59,5 @@ public class EventResponseModel : ResponseModel @@ -56,4 +59,5 @@ public class EventResponseModel : ResponseModel
public string DomainName { get; set; }
public Guid? SecretId { get; set; }
public Guid? ServiceAccountId { get; set; }
public string? SecretIds { get; set; }
}

7
src/Api/AdminConsole/Public/Models/Response/EventResponseModel.cs

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
using System.ComponentModel.DataAnnotations;
#nullable enable
using System.ComponentModel.DataAnnotations;
using Bit.Core.Enums;
using Bit.Core.Models.Data;
@ -29,6 +31,7 @@ public class EventResponseModel : IResponseModel @@ -29,6 +31,7 @@ public class EventResponseModel : IResponseModel
InstallationId = ev.InstallationId;
SecretId = ev.SecretId;
ServiceAccountId = ev.ServiceAccountId;
SecretIds = ev.SecretIds;
}
/// <summary>
@ -101,4 +104,6 @@ public class EventResponseModel : IResponseModel @@ -101,4 +104,6 @@ public class EventResponseModel : IResponseModel
/// </summary>
/// <example>e68b8629-85eb-4929-92c0-b84464976ba4</example>
public Guid? ServiceAccountId { get; set; }
public string? SecretIds { get; set; }
}

4
src/Api/SecretsManager/Controllers/SecretsController.cs

@ -231,7 +231,7 @@ public class SecretsController : Controller @@ -231,7 +231,7 @@ public class SecretsController : Controller
await _deleteSecretCommand.DeleteSecrets(secretsToDelete);
var responses = results.Select(r => new BulkDeleteResponseModel(r.Secret.Id, r.Error));
await LogSecretsEventAsync(secretsToDelete, EventType.Secret_Deleted);
await LogSecretsEventAsync(secretsToDelete, EventType.Secrets_Deleted_Bulk);
return new ListResponseModel<BulkDeleteResponseModel>(responses);
}
@ -251,7 +251,7 @@ public class SecretsController : Controller @@ -251,7 +251,7 @@ public class SecretsController : Controller
throw new NotFoundException();
}
await LogSecretsEventAsync(secrets, EventType.Secret_Retrieved);
await LogSecretsEventAsync(secrets, EventType.Secrets_Retrieved_Bulk);
var responses = secrets.Select(s => new BaseSecretResponseModel(s));
return new ListResponseModel<BaseSecretResponseModel>(responses);

2
src/Core/AdminConsole/Entities/Event.cs

@ -33,6 +33,7 @@ public class Event : ITableObject<Guid>, IEvent @@ -33,6 +33,7 @@ public class Event : ITableObject<Guid>, IEvent
DomainName = e.DomainName;
SecretId = e.SecretId;
ServiceAccountId = e.ServiceAccountId;
SecretIds = e.SecretIds;
}
public Guid Id { get; set; }
@ -57,6 +58,7 @@ public class Event : ITableObject<Guid>, IEvent @@ -57,6 +58,7 @@ public class Event : ITableObject<Guid>, IEvent
public string? DomainName { get; set; }
public Guid? SecretId { get; set; }
public Guid? ServiceAccountId { get; set; }
public string? SecretIds { get; set; }
public void SetNewId()
{

2
src/Core/AdminConsole/Enums/EventType.cs

@ -93,4 +93,6 @@ public enum EventType : int @@ -93,4 +93,6 @@ public enum EventType : int
Secret_Created = 2101,
Secret_Edited = 2102,
Secret_Deleted = 2103,
Secrets_Retrieved_Bulk = 2104,
Secrets_Deleted_Bulk = 2105,
}

19
src/Core/AdminConsole/Models/Data/EventMessage.cs

@ -1,4 +1,7 @@ @@ -1,4 +1,7 @@
using Bit.Core.Context;
#nullable enable
using System.ComponentModel.DataAnnotations;
using Bit.Core.Context;
using Bit.Core.Enums;
namespace Bit.Core.Models.Data;
@ -14,8 +17,10 @@ public class EventMessage : IEvent @@ -14,8 +17,10 @@ public class EventMessage : IEvent
DeviceType = currentContext.DeviceType;
}
public DateTime Date { get; set; }
public EventType Type { get; set; }
[Required]
public DateTime Date { get; set; } = DateTime.Now;
[Required]
public EventType Type { get; set; } = EventType.Cipher_Created;
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public Guid? InstallationId { get; set; }
@ -29,10 +34,14 @@ public class EventMessage : IEvent @@ -29,10 +34,14 @@ public class EventMessage : IEvent
public Guid? ProviderOrganizationId { get; set; }
public Guid? ActingUserId { get; set; }
public DeviceType? DeviceType { get; set; }
public string IpAddress { get; set; }
[Required]
public string IpAddress { get; set; } = string.Empty;
public Guid? IdempotencyId { get; private set; } = Guid.NewGuid();
public EventSystemUser? SystemUser { get; set; }
public string DomainName { get; set; }
[Required]
public string DomainName { get; set; } = string.Empty;
public Guid? SecretId { get; set; }
public string? SecretIds { get; set; }
public Guid? ServiceAccountId { get; set; }
}

18
src/Core/AdminConsole/Models/Data/EventTableEntity.cs

@ -33,6 +33,7 @@ public class AzureEvent : ITableEntity @@ -33,6 +33,7 @@ public class AzureEvent : ITableEntity
public string DomainName { get; set; }
public Guid? SecretId { get; set; }
public Guid? ServiceAccountId { get; set; }
public string SecretIds { get; set; }
public EventTableEntity ToEventTableEntity()
{
@ -62,7 +63,8 @@ public class AzureEvent : ITableEntity @@ -62,7 +63,8 @@ public class AzureEvent : ITableEntity
SystemUser = SystemUser.HasValue ? (EventSystemUser)SystemUser.Value : null,
DomainName = DomainName,
SecretId = SecretId,
ServiceAccountId = ServiceAccountId
ServiceAccountId = ServiceAccountId,
SecretIds = SecretIds,
};
}
}
@ -93,6 +95,7 @@ public class EventTableEntity : IEvent @@ -93,6 +95,7 @@ public class EventTableEntity : IEvent
DomainName = e.DomainName;
SecretId = e.SecretId;
ServiceAccountId = e.ServiceAccountId;
SecretIds = e.SecretIds;
}
public string PartitionKey { get; set; }
@ -120,6 +123,7 @@ public class EventTableEntity : IEvent @@ -120,6 +123,7 @@ public class EventTableEntity : IEvent
public string DomainName { get; set; }
public Guid? SecretId { get; set; }
public Guid? ServiceAccountId { get; set; }
public string SecretIds { get; set; }
public AzureEvent ToAzureEvent()
{
@ -149,7 +153,8 @@ public class EventTableEntity : IEvent @@ -149,7 +153,8 @@ public class EventTableEntity : IEvent
SystemUser = SystemUser.HasValue ? (int)SystemUser.Value : null,
DomainName = DomainName,
SecretId = SecretId,
ServiceAccountId = ServiceAccountId
ServiceAccountId = ServiceAccountId,
SecretIds = SecretIds
};
}
@ -215,6 +220,15 @@ public class EventTableEntity : IEvent @@ -215,6 +220,15 @@ public class EventTableEntity : IEvent
});
}
if (e.SecretIds != null)
{
entities.Add(new EventTableEntity(e)
{
PartitionKey = pKey,
RowKey = $"SecretIds={e.SecretIds}__Date={dateKey}__Uniquifier={uniquifier}"
});
}
return entities;
}

1
src/Core/AdminConsole/Models/Data/IEvent.cs

@ -24,4 +24,5 @@ public interface IEvent @@ -24,4 +24,5 @@ public interface IEvent
string DomainName { get; set; }
Guid? SecretId { get; set; }
Guid? ServiceAccountId { get; set; }
string SecretIds { get; set; }
}

111
src/Core/AdminConsole/Services/Implementations/EventService.cs

@ -414,48 +414,111 @@ public class EventService : IEventService @@ -414,48 +414,111 @@ public class EventService : IEventService
var orgAbilities = await _applicationCacheService.GetOrganizationAbilitiesAsync();
var eventMessages = new List<IEvent>();
foreach (var secret in secrets)
if (IsBulkEventType(type))
{
if (!CanUseEvents(orgAbilities, secret.OrganizationId))
var secretsByOrg = secrets.GroupBy(s => s.OrganizationId);
foreach (var group in secretsByOrg)
{
continue;
var orgId = group.Key;
if (!CanUseEvents(orgAbilities, orgId))
{
continue;
}
IEnumerable<Guid> secretIds = group.Select(s => s.Id);
var e = new EventMessage(_currentContext)
{
OrganizationId = orgId,
Type = type,
SecretIds = string.Join(",", secretIds.Select(id => id.ToString())),
UserId = userId,
Date = date.GetValueOrDefault(DateTime.UtcNow)
};
eventMessages.Add(e);
}
var e = new EventMessage(_currentContext)
}
else
{
foreach (var secret in secrets)
{
OrganizationId = secret.OrganizationId,
Type = type,
SecretId = secret.Id,
UserId = userId,
Date = date.GetValueOrDefault(DateTime.UtcNow)
};
eventMessages.Add(e);
if (!CanUseEvents(orgAbilities, secret.OrganizationId))
{
continue;
}
var e = new EventMessage(_currentContext)
{
OrganizationId = secret.OrganizationId,
Type = type,
SecretId = secret.Id,
UserId = userId,
Date = date.GetValueOrDefault(DateTime.UtcNow)
};
eventMessages.Add(e);
}
}
await _eventWriteService.CreateManyAsync(eventMessages);
}
public bool IsBulkEventType(EventType type)
{
return type == EventType.Secrets_Retrieved_Bulk || type == EventType.Secrets_Deleted_Bulk;
}
public async Task LogServiceAccountSecretsEventAsync(Guid serviceAccountId, IEnumerable<Secret> secrets, EventType type, DateTime? date = null)
{
var orgAbilities = await _applicationCacheService.GetOrganizationAbilitiesAsync();
var eventMessages = new List<IEvent>();
foreach (var secret in secrets)
if (IsBulkEventType(type))
{
if (!CanUseEvents(orgAbilities, secret.OrganizationId))
var secretsByOrg = secrets.GroupBy(s => s.OrganizationId);
foreach (var group in secretsByOrg)
{
continue;
var orgId = group.Key;
if (!CanUseEvents(orgAbilities, orgId))
{
continue;
}
IEnumerable<Guid> secretIds = group.Select(s => s.Id);
var e = new EventMessage(_currentContext)
{
OrganizationId = orgId,
Type = type,
SecretIds = string.Join(",", secretIds.Select(id => id.ToString())),
UserId = serviceAccountId,
Date = date.GetValueOrDefault(DateTime.UtcNow)
};
eventMessages.Add(e);
}
var e = new EventMessage(_currentContext)
}
else
{
foreach (var secret in secrets)
{
OrganizationId = secret.OrganizationId,
Type = type,
SecretId = secret.Id,
ServiceAccountId = serviceAccountId,
Date = date.GetValueOrDefault(DateTime.UtcNow)
};
eventMessages.Add(e);
if (!CanUseEvents(orgAbilities, secret.OrganizationId))
{
continue;
}
var e = new EventMessage(_currentContext)
{
OrganizationId = secret.OrganizationId,
Type = type,
SecretId = secret.Id,
ServiceAccountId = serviceAccountId,
Date = date.GetValueOrDefault(DateTime.UtcNow)
};
eventMessages.Add(e);
}
}
await _eventWriteService.CreateManyAsync(eventMessages);

Loading…
Cancel
Save