mirror of
https://github.com/bitwarden/server.git
synced 2025-01-10 20:07:56 +01:00
event sql table and repo
This commit is contained in:
parent
7b359053d6
commit
ce1680a009
@ -3,7 +3,7 @@ using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
public class Event : IEvent
|
||||
public class EventMessage : IEvent
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
public EventType Type { get; set; }
|
@ -5,7 +5,6 @@ namespace Bit.Core.Models.Data
|
||||
{
|
||||
public interface IEvent
|
||||
{
|
||||
DateTime Date { get; set; }
|
||||
EventType Type { get; set; }
|
||||
Guid? UserId { get; set; }
|
||||
Guid? OrganizationId { get; set; }
|
||||
@ -14,5 +13,6 @@ namespace Bit.Core.Models.Data
|
||||
Guid? GroupId { get; set; }
|
||||
Guid? OrganizationUserId { get; set; }
|
||||
Guid? ActingUserId { get; set; }
|
||||
DateTime Date { get; set; }
|
||||
}
|
||||
}
|
||||
|
41
src/Core/Models/Table/Event.cs
Normal file
41
src/Core/Models/Table/Event.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Models.Table
|
||||
{
|
||||
public class Event : ITableObject<Guid>, IEvent
|
||||
{
|
||||
public Event() { }
|
||||
|
||||
public Event(IEvent e)
|
||||
{
|
||||
Date = e.Date;
|
||||
Type = e.Type;
|
||||
UserId = e.UserId;
|
||||
OrganizationId = e.OrganizationId;
|
||||
CipherId = e.CipherId;
|
||||
CollectionId = e.CollectionId;
|
||||
GroupId = e.GroupId;
|
||||
OrganizationUserId = e.OrganizationUserId;
|
||||
ActingUserId = e.ActingUserId;
|
||||
}
|
||||
|
||||
public Guid Id { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public EventType Type { get; set; }
|
||||
public Guid? UserId { get; set; }
|
||||
public Guid? OrganizationId { get; set; }
|
||||
public Guid? CipherId { get; set; }
|
||||
public Guid? CollectionId { get; set; }
|
||||
public Guid? GroupId { get; set; }
|
||||
public Guid? OrganizationUserId { get; set; }
|
||||
public Guid? ActingUserId { get; set; }
|
||||
|
||||
public void SetNewId()
|
||||
{
|
||||
Id = CoreHelpers.GenerateComb();
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ namespace Bit.Core.Repositories
|
||||
public interface IEventRepository
|
||||
{
|
||||
Task<ICollection<IEvent>> GetManyByUserAsync(Guid userId, DateTime startDate, DateTime endDate);
|
||||
Task CreateAsync(IEvent entity);
|
||||
Task CreateManyAsync(IList<IEvent> entities);
|
||||
Task CreateAsync(IEvent e);
|
||||
Task CreateManyAsync(IList<IEvent> e);
|
||||
}
|
||||
}
|
||||
|
@ -392,8 +392,7 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
{
|
||||
if(folders.Any())
|
||||
{
|
||||
using(var bulkCopy = new SqlBulkCopy(connection,
|
||||
SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers, transaction))
|
||||
using(var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction))
|
||||
{
|
||||
bulkCopy.DestinationTableName = "[dbo].[Folder]";
|
||||
var dataTable = BuildFoldersTable(folders);
|
||||
@ -401,8 +400,7 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
using(var bulkCopy = new SqlBulkCopy(connection,
|
||||
SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers, transaction))
|
||||
using(var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction))
|
||||
{
|
||||
bulkCopy.DestinationTableName = "[dbo].[Cipher]";
|
||||
var dataTable = BuildCiphersTable(ciphers);
|
||||
|
115
src/Core/Repositories/SqlServer/EventRepository.cs
Normal file
115
src/Core/Repositories/SqlServer/EventRepository.cs
Normal file
@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using Bit.Core.Models.Table;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Bit.Core.Models.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Data;
|
||||
|
||||
namespace Bit.Core.Repositories.SqlServer
|
||||
{
|
||||
public class EventRepository : Repository<Event, Guid>, IEventRepository
|
||||
{
|
||||
public EventRepository(GlobalSettings globalSettings)
|
||||
: this(globalSettings.SqlServer.ConnectionString)
|
||||
{ }
|
||||
|
||||
public EventRepository(string connectionString)
|
||||
: base(connectionString)
|
||||
{ }
|
||||
|
||||
public Task<ICollection<IEvent>> GetManyByUserAsync(Guid userId, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task CreateAsync(IEvent e)
|
||||
{
|
||||
if(!(e is Event ev))
|
||||
{
|
||||
ev = new Event(e);
|
||||
}
|
||||
|
||||
await base.CreateAsync(ev);
|
||||
}
|
||||
|
||||
public async Task CreateManyAsync(IList<IEvent> entities)
|
||||
{
|
||||
if(!entities.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using(var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
connection.Open();
|
||||
using(var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, null))
|
||||
{
|
||||
bulkCopy.DestinationTableName = "[dbo].[Event]";
|
||||
var dataTable = BuildEventsTable(entities.Select(e => e is Event ? e as Event : new Event(e)));
|
||||
await bulkCopy.WriteToServerAsync(dataTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DataTable BuildEventsTable(IEnumerable<Event> events)
|
||||
{
|
||||
var e = events.FirstOrDefault();
|
||||
if(e == null)
|
||||
{
|
||||
throw new ApplicationException("Must have some events to bulk import.");
|
||||
}
|
||||
|
||||
var eventsTable = new DataTable("EventDataTable");
|
||||
|
||||
var idColumn = new DataColumn(nameof(e.Id), e.Id.GetType());
|
||||
eventsTable.Columns.Add(idColumn);
|
||||
var typeColumn = new DataColumn(nameof(e.Type), typeof(int));
|
||||
eventsTable.Columns.Add(typeColumn);
|
||||
var dateColumn = new DataColumn(nameof(e.Date), e.Date.GetType());
|
||||
eventsTable.Columns.Add(dateColumn);
|
||||
var userIdColumn = new DataColumn(nameof(e.UserId), typeof(Guid));
|
||||
eventsTable.Columns.Add(userIdColumn);
|
||||
var organizationIdColumn = new DataColumn(nameof(e.OrganizationId), typeof(Guid));
|
||||
eventsTable.Columns.Add(organizationIdColumn);
|
||||
var cipherIdColumn = new DataColumn(nameof(e.CipherId), typeof(Guid));
|
||||
eventsTable.Columns.Add(cipherIdColumn);
|
||||
var groupIdColumn = new DataColumn(nameof(e.GroupId), typeof(Guid));
|
||||
eventsTable.Columns.Add(groupIdColumn);
|
||||
var collectionIdColumn = new DataColumn(nameof(e.CollectionId), typeof(Guid));
|
||||
eventsTable.Columns.Add(collectionIdColumn);
|
||||
var actingUserIdColumn = new DataColumn(nameof(e.ActingUserId), typeof(Guid));
|
||||
eventsTable.Columns.Add(actingUserIdColumn);
|
||||
var organizationUserIdColumn = new DataColumn(nameof(e.OrganizationUserId), typeof(Guid));
|
||||
eventsTable.Columns.Add(organizationUserIdColumn);
|
||||
|
||||
var keys = new DataColumn[1];
|
||||
keys[0] = idColumn;
|
||||
eventsTable.PrimaryKey = keys;
|
||||
|
||||
foreach(var ev in events)
|
||||
{
|
||||
ev.SetNewId();
|
||||
|
||||
var row = eventsTable.NewRow();
|
||||
|
||||
row[idColumn] = ev.Id;
|
||||
row[typeColumn] = ev.Type;
|
||||
row[dateColumn] = ev.Date;
|
||||
row[userIdColumn] = ev.UserId;
|
||||
row[organizationIdColumn] = ev.OrganizationId;
|
||||
row[cipherIdColumn] = ev.CipherId;
|
||||
row[groupIdColumn] = ev.GroupId;
|
||||
row[collectionIdColumn] = ev.CollectionId;
|
||||
row[actingUserIdColumn] = ev.ActingUserId;
|
||||
row[organizationUserIdColumn] = ev.OrganizationUserId;
|
||||
|
||||
eventsTable.Rows.Add(row);
|
||||
}
|
||||
|
||||
return eventsTable;
|
||||
}
|
||||
}
|
||||
}
|
@ -33,7 +33,7 @@ namespace Bit.Core.Services
|
||||
var now = DateTime.UtcNow;
|
||||
var events = new List<IEvent>
|
||||
{
|
||||
new Event
|
||||
new EventMessage
|
||||
{
|
||||
UserId = userId,
|
||||
Type = type,
|
||||
@ -44,7 +44,7 @@ namespace Bit.Core.Services
|
||||
IEnumerable<IEvent> orgEvents;
|
||||
if(_currentContext.UserId.HasValue)
|
||||
{
|
||||
orgEvents = _currentContext.Organizations.Select(o => new Event
|
||||
orgEvents = _currentContext.Organizations.Select(o => new EventMessage
|
||||
{
|
||||
OrganizationId = o.Id,
|
||||
UserId = userId,
|
||||
@ -56,7 +56,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var orgs = await _organizationUserRepository.GetManyByUserAsync(userId);
|
||||
orgEvents = orgs.Where(o => o.Status == OrganizationUserStatusType.Confirmed)
|
||||
.Select(o => new Event
|
||||
.Select(o => new EventMessage
|
||||
{
|
||||
OrganizationId = o.Id,
|
||||
UserId = userId,
|
||||
@ -83,7 +83,7 @@ namespace Bit.Core.Services
|
||||
return;
|
||||
}
|
||||
|
||||
var e = new Event
|
||||
var e = new EventMessage
|
||||
{
|
||||
OrganizationId = cipher.OrganizationId,
|
||||
UserId = cipher.OrganizationId.HasValue ? null : cipher.UserId,
|
||||
@ -97,7 +97,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task LogCollectionEventAsync(Collection collection, EventType type)
|
||||
{
|
||||
var e = new Event
|
||||
var e = new EventMessage
|
||||
{
|
||||
OrganizationId = collection.OrganizationId,
|
||||
CollectionId = collection.Id,
|
||||
@ -110,7 +110,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task LogGroupEventAsync(Group group, EventType type)
|
||||
{
|
||||
var e = new Event
|
||||
var e = new EventMessage
|
||||
{
|
||||
OrganizationId = group.OrganizationId,
|
||||
GroupId = group.Id,
|
||||
@ -123,7 +123,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task LogOrganizationUserEventAsync(OrganizationUser organizationUser, EventType type)
|
||||
{
|
||||
var e = new Event
|
||||
var e = new EventMessage
|
||||
{
|
||||
OrganizationId = organizationUser.OrganizationId,
|
||||
UserId = organizationUser.UserId,
|
||||
@ -137,7 +137,7 @@ namespace Bit.Core.Services
|
||||
|
||||
public async Task LogOrganizationEventAsync(Organization organization, EventType type)
|
||||
{
|
||||
var e = new Event
|
||||
var e = new EventMessage
|
||||
{
|
||||
OrganizationId = organization.Id,
|
||||
Type = type,
|
||||
|
@ -44,7 +44,7 @@ namespace Bit.Core.Utilities
|
||||
|
||||
if(globalSettings.SelfHosted)
|
||||
{
|
||||
// TODO: Sql server event repo
|
||||
services.AddSingleton<IEventRepository, SqlServerRepos.EventRepository>();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -42,13 +42,13 @@ namespace Bit.EventsProcessor
|
||||
var token = JToken.Parse(message);
|
||||
if(token is JArray)
|
||||
{
|
||||
var events = token.ToObject<List<Event>>()
|
||||
var events = token.ToObject<List<EventMessage>>()
|
||||
.Select(e => new EventTableEntity(e) as IEvent).ToList();
|
||||
await _eventWriteService.CreateManyAsync(events);
|
||||
}
|
||||
else if(token is JObject)
|
||||
{
|
||||
var e = token.ToObject<Event>();
|
||||
var e = token.ToObject<EventMessage>();
|
||||
await _eventWriteService.CreateAsync(new EventTableEntity(e));
|
||||
}
|
||||
}
|
||||
|
39
src/Sql/dbo/Stored Procedures/Event_Create.sql
Normal file
39
src/Sql/dbo/Stored Procedures/Event_Create.sql
Normal file
@ -0,0 +1,39 @@
|
||||
CREATE PROCEDURE [dbo].[Event_Create]
|
||||
@Id UNIQUEIDENTIFIER,
|
||||
@Type INT,
|
||||
@UserId UNIQUEIDENTIFIER,
|
||||
@OrganizationId UNIQUEIDENTIFIER,
|
||||
@CipherId UNIQUEIDENTIFIER,
|
||||
@CollectionId UNIQUEIDENTIFIER,
|
||||
@GroupId UNIQUEIDENTIFIER,
|
||||
@OrganizationUserId UNIQUEIDENTIFIER,
|
||||
@Date DATETIME2(7)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
INSERT INTO [dbo].[Event]
|
||||
(
|
||||
[Id],
|
||||
[Type],
|
||||
[UserId],
|
||||
[OrganizationId],
|
||||
[CipherId],
|
||||
[CollectionId],
|
||||
[GroupId],
|
||||
[OrganizationUserId],
|
||||
[Date]
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@Id,
|
||||
@Type,
|
||||
@UserId,
|
||||
@OrganizationId,
|
||||
@CipherId,
|
||||
@CollectionId,
|
||||
@GroupId,
|
||||
@OrganizationUserId,
|
||||
@Date
|
||||
)
|
||||
END
|
13
src/Sql/dbo/Tables/Event.sql
Normal file
13
src/Sql/dbo/Tables/Event.sql
Normal file
@ -0,0 +1,13 @@
|
||||
CREATE TABLE [dbo].[Event] (
|
||||
[Id] UNIQUEIDENTIFIER NOT NULL,
|
||||
[Type] INT NOT NULL,
|
||||
[UserId] UNIQUEIDENTIFIER NULL,
|
||||
[OrganizationId] UNIQUEIDENTIFIER NULL,
|
||||
[CipherId] UNIQUEIDENTIFIER NULL,
|
||||
[CollectionId] UNIQUEIDENTIFIER NULL,
|
||||
[GroupId] UNIQUEIDENTIFIER NULL,
|
||||
[OrganizationUserId] UNIQUEIDENTIFIER NULL,
|
||||
[Date] DATETIME2 (7) NOT NULL,
|
||||
CONSTRAINT [PK_Event] PRIMARY KEY CLUSTERED ([Id] ASC)
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user