diff --git a/src/Core/Enums/EventType.cs b/src/Core/Enums/EventType.cs index d9411e31c4..cba879d938 100644 --- a/src/Core/Enums/EventType.cs +++ b/src/Core/Enums/EventType.cs @@ -44,5 +44,9 @@ Organization_Updated = 1600, Organization_PurgedVault = 1601, // Organization_ClientExportedVault = 1602, + + Policy_Created = 1700, + Policy_Updated = 1701, + Policy_Deleted = 1702, } } diff --git a/src/Core/Models/Api/Public/Response/EventResponseModel.cs b/src/Core/Models/Api/Public/Response/EventResponseModel.cs index c9575151e1..8d3ba5b33d 100644 --- a/src/Core/Models/Api/Public/Response/EventResponseModel.cs +++ b/src/Core/Models/Api/Public/Response/EventResponseModel.cs @@ -21,6 +21,7 @@ namespace Bit.Core.Models.Api.Public ItemId = ev.CipherId; CollectionId = ev.CollectionId; GroupId = ev.GroupId; + PolicyId = ev.PolicyId; MemberId = ev.OrganizationUserId; ActingUserId = ev.ActingUserId; Date = ev.Date; @@ -55,6 +56,11 @@ namespace Bit.Core.Models.Api.Public /// f29a2515-91d2-4452-b49b-5e8040e6b0f4 public Guid? GroupId { get; set; } /// + /// The unique identifier of the related policy that the event describes. + /// + /// f29a2515-91d2-4452-b49b-5e8040e6b0f4 + public Guid? PolicyId { get; set; } + /// /// The unique identifier of the related member that the event describes. /// /// e68b8629-85eb-4929-92c0-b84464976ba4 diff --git a/src/Core/Models/Api/Response/EventResponseModel.cs b/src/Core/Models/Api/Response/EventResponseModel.cs index 033748a4e3..6f15136eed 100644 --- a/src/Core/Models/Api/Response/EventResponseModel.cs +++ b/src/Core/Models/Api/Response/EventResponseModel.cs @@ -20,6 +20,7 @@ namespace Bit.Core.Models.Api CipherId = ev.CipherId; CollectionId = ev.CollectionId; GroupId = ev.GroupId; + PolicyId = ev.PolicyId; OrganizationUserId = ev.OrganizationUserId; ActingUserId = ev.ActingUserId; Date = ev.Date; @@ -33,6 +34,7 @@ namespace Bit.Core.Models.Api public Guid? CipherId { get; set; } public Guid? CollectionId { get; set; } public Guid? GroupId { get; set; } + public Guid? PolicyId { get; set; } public Guid? OrganizationUserId { get; set; } public Guid? ActingUserId { get; set; } public DateTime Date { get; set; } diff --git a/src/Core/Models/Data/EventMessage.cs b/src/Core/Models/Data/EventMessage.cs index 452853bfed..8df07d49a7 100644 --- a/src/Core/Models/Data/EventMessage.cs +++ b/src/Core/Models/Data/EventMessage.cs @@ -21,6 +21,7 @@ namespace Bit.Core.Models.Data public Guid? CipherId { get; set; } public Guid? CollectionId { get; set; } public Guid? GroupId { get; set; } + public Guid? PolicyId { get; set; } public Guid? OrganizationUserId { get; set; } public Guid? ActingUserId { get; set; } public DeviceType? DeviceType { get; set; } diff --git a/src/Core/Models/Data/EventTableEntity.cs b/src/Core/Models/Data/EventTableEntity.cs index 56c753d260..a7a8d3219e 100644 --- a/src/Core/Models/Data/EventTableEntity.cs +++ b/src/Core/Models/Data/EventTableEntity.cs @@ -18,6 +18,7 @@ namespace Bit.Core.Models.Data OrganizationId = e.OrganizationId; CipherId = e.CipherId; CollectionId = e.CollectionId; + PolicyId = e.PolicyId; GroupId = e.GroupId; OrganizationUserId = e.OrganizationUserId; DeviceType = e.DeviceType; @@ -31,6 +32,7 @@ namespace Bit.Core.Models.Data public Guid? OrganizationId { 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 DeviceType? DeviceType { get; set; } diff --git a/src/Core/Models/Data/IEvent.cs b/src/Core/Models/Data/IEvent.cs index eba891dd9f..8d8204c1a8 100644 --- a/src/Core/Models/Data/IEvent.cs +++ b/src/Core/Models/Data/IEvent.cs @@ -11,6 +11,7 @@ namespace Bit.Core.Models.Data Guid? CipherId { get; set; } Guid? CollectionId { get; set; } Guid? GroupId { get; set; } + Guid? PolicyId { get; set; } Guid? OrganizationUserId { get; set; } Guid? ActingUserId { get; set; } DeviceType? DeviceType { get; set; } diff --git a/src/Core/Models/Table/Event.cs b/src/Core/Models/Table/Event.cs index 2e5c60dd05..6b00a7b81c 100644 --- a/src/Core/Models/Table/Event.cs +++ b/src/Core/Models/Table/Event.cs @@ -17,6 +17,7 @@ namespace Bit.Core.Models.Table OrganizationId = e.OrganizationId; CipherId = e.CipherId; CollectionId = e.CollectionId; + PolicyId = e.PolicyId; GroupId = e.GroupId; OrganizationUserId = e.OrganizationUserId; DeviceType = e.DeviceType; @@ -31,6 +32,7 @@ namespace Bit.Core.Models.Table public Guid? OrganizationId { 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 DeviceType? DeviceType { get; set; } diff --git a/src/Core/Repositories/SqlServer/EventRepository.cs b/src/Core/Repositories/SqlServer/EventRepository.cs index f8ec8545ec..4481f6f9b1 100644 --- a/src/Core/Repositories/SqlServer/EventRepository.cs +++ b/src/Core/Repositories/SqlServer/EventRepository.cs @@ -153,6 +153,8 @@ namespace Bit.Core.Repositories.SqlServer eventsTable.Columns.Add(cipherIdColumn); var collectionIdColumn = new DataColumn(nameof(e.CollectionId), typeof(Guid)); eventsTable.Columns.Add(collectionIdColumn); + var policyIdColumn = new DataColumn(nameof(e.PolicyId), typeof(Guid)); + eventsTable.Columns.Add(policyIdColumn); var groupIdColumn = new DataColumn(nameof(e.GroupId), typeof(Guid)); eventsTable.Columns.Add(groupIdColumn); var organizationUserIdColumn = new DataColumn(nameof(e.OrganizationUserId), typeof(Guid)); @@ -182,6 +184,7 @@ namespace Bit.Core.Repositories.SqlServer row[organizationIdColumn] = ev.OrganizationId.HasValue ? (object)ev.OrganizationId.Value : DBNull.Value; row[cipherIdColumn] = ev.CipherId.HasValue ? (object)ev.CipherId.Value : DBNull.Value; row[collectionIdColumn] = ev.CollectionId.HasValue ? (object)ev.CollectionId.Value : DBNull.Value; + row[policyIdColumn] = ev.PolicyId.HasValue ? (object)ev.PolicyId.Value : DBNull.Value; row[groupIdColumn] = ev.GroupId.HasValue ? (object)ev.GroupId.Value : DBNull.Value; row[organizationUserIdColumn] = ev.OrganizationUserId.HasValue ? (object)ev.OrganizationUserId.Value : DBNull.Value; diff --git a/src/Core/Services/IEventService.cs b/src/Core/Services/IEventService.cs index cb0fa70287..0acc344612 100644 --- a/src/Core/Services/IEventService.cs +++ b/src/Core/Services/IEventService.cs @@ -13,6 +13,7 @@ namespace Bit.Core.Services Task LogCipherEventsAsync(IEnumerable> events); Task LogCollectionEventAsync(Collection collection, EventType type, DateTime? date = null); Task LogGroupEventAsync(Group group, EventType type, DateTime? date = null); + Task LogPolicyEventAsync(Policy policy, EventType type, DateTime? date = null); Task LogOrganizationUserEventAsync(OrganizationUser organizationUser, EventType type, DateTime? date = null); Task LogOrganizationEventAsync(Organization organization, EventType type, DateTime? date = null); } diff --git a/src/Core/Services/Implementations/EventService.cs b/src/Core/Services/Implementations/EventService.cs index 043f1786cf..6e62b0b09b 100644 --- a/src/Core/Services/Implementations/EventService.cs +++ b/src/Core/Services/Implementations/EventService.cs @@ -156,6 +156,25 @@ namespace Bit.Core.Services await _eventWriteService.CreateAsync(e); } + public async Task LogPolicyEventAsync(Policy policy, EventType type, DateTime? date = null) + { + var orgAbilities = await _applicationCacheService.GetOrganizationAbilitiesAsync(); + if(!CanUseEvents(orgAbilities, policy.OrganizationId)) + { + return; + } + + var e = new EventMessage(_currentContext) + { + OrganizationId = policy.OrganizationId, + PolicyId = policy.Id, + Type = type, + ActingUserId = _currentContext?.UserId, + Date = date.GetValueOrDefault(DateTime.UtcNow) + }; + await _eventWriteService.CreateAsync(e); + } + public async Task LogOrganizationUserEventAsync(OrganizationUser organizationUser, EventType type, DateTime? date = null) { diff --git a/src/Core/Services/Implementations/PolicyService.cs b/src/Core/Services/Implementations/PolicyService.cs index 7e7f7c80d5..9045ad6d00 100644 --- a/src/Core/Services/Implementations/PolicyService.cs +++ b/src/Core/Services/Implementations/PolicyService.cs @@ -3,8 +3,6 @@ using System.Threading.Tasks; using Bit.Core.Exceptions; using Bit.Core.Models.Table; using Bit.Core.Repositories; -using System.Collections.Generic; -using Bit.Core.Models.Data; namespace Bit.Core.Services { @@ -46,20 +44,20 @@ namespace Bit.Core.Services { policy.CreationDate = policy.RevisionDate = DateTime.UtcNow; await _policyRepository.CreateAsync(policy); - //await _eventService.LogGroupEventAsync(policy, Enums.EventType.Group_Created); + await _eventService.LogPolicyEventAsync(policy, Enums.EventType.Policy_Created); } else { policy.RevisionDate = DateTime.UtcNow; await _policyRepository.ReplaceAsync(policy); - //await _eventService.LogGroupEventAsync(policy, Enums.EventType.Group_Updated); + await _eventService.LogPolicyEventAsync(policy, Enums.EventType.Policy_Updated); } } public async Task DeleteAsync(Policy policy) { await _policyRepository.DeleteAsync(policy); - //await _eventService.LogGroupEventAsync(policy, Enums.EventType.Group_Deleted); + await _eventService.LogPolicyEventAsync(policy, Enums.EventType.Policy_Deleted); } } } diff --git a/src/Core/Services/NoopImplementations/NoopEventService.cs b/src/Core/Services/NoopImplementations/NoopEventService.cs index 462c4e1f48..1a3fa27efd 100644 --- a/src/Core/Services/NoopImplementations/NoopEventService.cs +++ b/src/Core/Services/NoopImplementations/NoopEventService.cs @@ -23,6 +23,11 @@ namespace Bit.Core.Services return Task.FromResult(0); } + public Task LogPolicyEventAsync(Policy policy, EventType type, DateTime? date = null) + { + return Task.FromResult(0); + } + public Task LogGroupEventAsync(Group group, EventType type, DateTime? date = null) { return Task.FromResult(0); diff --git a/src/Sql/dbo/Stored Procedures/Event_Create.sql b/src/Sql/dbo/Stored Procedures/Event_Create.sql index 1e3989f1cf..558e0339eb 100644 --- a/src/Sql/dbo/Stored Procedures/Event_Create.sql +++ b/src/Sql/dbo/Stored Procedures/Event_Create.sql @@ -5,6 +5,7 @@ @OrganizationId UNIQUEIDENTIFIER, @CipherId UNIQUEIDENTIFIER, @CollectionId UNIQUEIDENTIFIER, + @PolicyId UNIQUEIDENTIFIER, @GroupId UNIQUEIDENTIFIER, @OrganizationUserId UNIQUEIDENTIFIER, @ActingUserId UNIQUEIDENTIFIER, @@ -23,6 +24,7 @@ BEGIN [OrganizationId], [CipherId], [CollectionId], + [PolicyId], [GroupId], [OrganizationUserId], [ActingUserId], @@ -38,6 +40,7 @@ BEGIN @OrganizationId, @CipherId, @CollectionId, + @PolicyId, @GroupId, @OrganizationUserId, @ActingUserId, diff --git a/src/Sql/dbo/Tables/Event.sql b/src/Sql/dbo/Tables/Event.sql index debc0abea8..7e53aaac67 100644 --- a/src/Sql/dbo/Tables/Event.sql +++ b/src/Sql/dbo/Tables/Event.sql @@ -5,6 +5,7 @@ [OrganizationId] UNIQUEIDENTIFIER NULL, [CipherId] UNIQUEIDENTIFIER NULL, [CollectionId] UNIQUEIDENTIFIER NULL, + [PolicyId] UNIQUEIDENTIFIER NULL, [GroupId] UNIQUEIDENTIFIER NULL, [OrganizationUserId] UNIQUEIDENTIFIER NULL, [ActingUserId] UNIQUEIDENTIFIER NULL, diff --git a/util/Migrator/DbScripts/2020-01-06_00_PolicySetup.sql b/util/Migrator/DbScripts/2020-01-15_00_PolicySetup.sql similarity index 71% rename from util/Migrator/DbScripts/2020-01-06_00_PolicySetup.sql rename to util/Migrator/DbScripts/2020-01-15_00_PolicySetup.sql index f7cfcd495e..0a08bd509a 100644 --- a/util/Migrator/DbScripts/2020-01-06_00_PolicySetup.sql +++ b/util/Migrator/DbScripts/2020-01-15_00_PolicySetup.sql @@ -175,3 +175,85 @@ SELECT FROM [dbo].[Policy] GO + +IF COL_LENGTH('[dbo].[Event]', 'PolicyId') IS NULL +BEGIN + ALTER TABLE + [dbo].[Event] + ADD + [PolicyId] UNIQUEIDENTIFIER NULL +END +GO + +IF EXISTS(SELECT * FROM sys.views WHERE [Name] = 'EventView') +BEGIN + DROP VIEW [dbo].[EventView] +END +GO + +CREATE VIEW [dbo].[EventView] +AS +SELECT + * +FROM + [dbo].[Event] +GO + +IF OBJECT_ID('[dbo].[Event_Create]') IS NOT NULL +BEGIN + DROP PROCEDURE [dbo].[Event_Create] +END +GO + +CREATE PROCEDURE [dbo].[Event_Create] + @Id UNIQUEIDENTIFIER, + @Type INT, + @UserId UNIQUEIDENTIFIER, + @OrganizationId UNIQUEIDENTIFIER, + @CipherId UNIQUEIDENTIFIER, + @CollectionId UNIQUEIDENTIFIER, + @PolicyId UNIQUEIDENTIFIER, + @GroupId UNIQUEIDENTIFIER, + @OrganizationUserId UNIQUEIDENTIFIER, + @ActingUserId UNIQUEIDENTIFIER, + @DeviceType SMALLINT, + @IpAddress VARCHAR(50), + @Date DATETIME2(7) +AS +BEGIN + SET NOCOUNT ON + + INSERT INTO [dbo].[Event] + ( + [Id], + [Type], + [UserId], + [OrganizationId], + [CipherId], + [CollectionId], + [PolicyId], + [GroupId], + [OrganizationUserId], + [ActingUserId], + [DeviceType], + [IpAddress], + [Date] + ) + VALUES + ( + @Id, + @Type, + @UserId, + @OrganizationId, + @CipherId, + @CollectionId, + @PolicyId, + @GroupId, + @OrganizationUserId, + @ActingUserId, + @DeviceType, + @IpAddress, + @Date + ) +END +GO