From 5c77ae98100f24aa0686644e86b001baf5b8e617 Mon Sep 17 00:00:00 2001 From: Vijay Oommen Date: Mon, 23 Feb 2026 17:00:21 -0600 Subject: [PATCH] PM-31725 updated properties to match the pull in public/events (#6959) --- .../IntegrationTemplateContext.cs | 4 + .../Services/EventIntegrationHandlerTests.cs | 101 ++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/src/Core/Dirt/Models/Data/EventIntegrations/IntegrationTemplateContext.cs b/src/Core/Dirt/Models/Data/EventIntegrations/IntegrationTemplateContext.cs index 3b527469fa..d31f3a961c 100644 --- a/src/Core/Dirt/Models/Data/EventIntegrations/IntegrationTemplateContext.cs +++ b/src/Core/Dirt/Models/Data/EventIntegrations/IntegrationTemplateContext.cs @@ -13,10 +13,12 @@ public class IntegrationTemplateContext(EventMessage eventMessage) public string DomainName => Event.DomainName; public string IpAddress => Event.IpAddress; public DeviceType? DeviceType => Event.DeviceType; + public int? DeviceTypeId => Event.DeviceType is not null ? (int)Event.DeviceType : null; public Guid? ActingUserId => Event.ActingUserId; public Guid? OrganizationUserId => Event.OrganizationUserId; public DateTime Date => Event.Date; public EventType Type => Event.Type; + public int TypeId => (int)Event.Type; public Guid? UserId => Event.UserId; public Guid? OrganizationId => Event.OrganizationId; public Guid? CipherId => Event.CipherId; @@ -51,4 +53,6 @@ public class IntegrationTemplateContext(EventMessage eventMessage) public Organization? Organization { get; set; } public string? OrganizationName => Organization?.DisplayName(); + + public int? SystemUser => Event.SystemUser is not null ? (int)Event.SystemUser : null; } diff --git a/test/Core.Test/Dirt/Services/EventIntegrationHandlerTests.cs b/test/Core.Test/Dirt/Services/EventIntegrationHandlerTests.cs index e15a254b39..8a55875742 100644 --- a/test/Core.Test/Dirt/Services/EventIntegrationHandlerTests.cs +++ b/test/Core.Test/Dirt/Services/EventIntegrationHandlerTests.cs @@ -1,6 +1,7 @@ #nullable enable using System.Text.Json; +using System.Text.Json.Nodes; using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Repositories; using Bit.Core.Dirt.Enums; @@ -708,4 +709,104 @@ public class EventIntegrationHandlerTests Assert.NotNull(capturedTags); Assert.Contains(expectedTag, capturedTags); } + + [Theory, BitAutoData] + public async Task HandleEventAsync_SubstituteTemplateTags(EventMessage eventMessage) + { + eventMessage.OrganizationId = _organizationId; + var templateJson = @"{ + ""bw_serviceName"": ""bitwarden"", + ""ddsource"": ""bitwarden"", + ""service"": ""event-logs"", + ""event"": { + ""object"": ""event"", + ""type"": ""#TypeId#"", + ""typeName"": ""#Type#"", + ""userId"": ""#UserId#"", + ""organizationId"": ""#OrganizationId#"", + ""providerId"": ""#ProviderId#"", + ""cipherId"": ""#CipherId#"", + ""collectionId"": ""#CollectionId#"", + ""groupId"": ""#GroupId#"", + ""policyId"": ""#PolicyId#"", + ""organizationUserId"": ""#OrganizationUserId#"", + ""providerUserId"": ""#ProviderUserId#"", + ""providerOrganizationId"": ""#ProviderOrganizationId#"", + ""actingUserId"": ""#ActingUserId#"", + ""installationId"": ""#InstallationId#"", + ""date"": ""#DateIso8601#"", + ""deviceType"": ""#DeviceType#"", + ""deviceTypeId"": ""#DeviceTypeId#"", + ""ipAddress"": ""#IpAddress#"", + ""systemUser"": ""#SystemUser#"", + ""domainName"": ""#DomainName#"", + ""secretId"": ""#SecretId#"", + ""projectId"": ""#ProjectId#"", + ""serviceAccountId"": ""#ServiceAccountId#"" + } + }"; + var sutProvider = GetSutProvider(OneConfiguration(templateJson)); + + await sutProvider.Sut.HandleEventAsync(eventMessage); + + var deviceTypeId = eventMessage.DeviceType is not null ? (int)eventMessage.DeviceType : (int?)null; + var systemUser = eventMessage.SystemUser is not null ? (int)eventMessage.SystemUser : (int?)null; + + var parsedJson = $@"{{ + ""bw_serviceName"": ""bitwarden"", + ""ddsource"": ""bitwarden"", + ""service"": ""event-logs"", + ""event"": {{ + ""object"": ""event"", + ""type"": ""{(int)eventMessage.Type}"", + ""typeName"": ""{eventMessage.Type}"", + ""userId"": ""{eventMessage.UserId}"", + ""organizationId"": ""{eventMessage.OrganizationId}"", + ""providerId"": ""{eventMessage.ProviderId}"", + ""cipherId"": ""{eventMessage.CipherId}"", + ""collectionId"": ""{eventMessage.CollectionId}"", + ""groupId"": ""{eventMessage.GroupId}"", + ""policyId"": ""{eventMessage.PolicyId}"", + ""organizationUserId"": ""{eventMessage.OrganizationUserId}"", + ""providerUserId"": ""{eventMessage.ProviderUserId}"", + ""providerOrganizationId"": ""{eventMessage.ProviderOrganizationId}"", + ""actingUserId"": ""{eventMessage.ActingUserId}"", + ""installationId"": ""{eventMessage.InstallationId}"", + ""date"": ""{eventMessage.Date.ToString("o")}"", + ""deviceType"": ""{eventMessage.DeviceType}"", + ""deviceTypeId"": ""{deviceTypeId}"", + ""ipAddress"": ""{eventMessage.IpAddress}"", + ""systemUser"": ""{systemUser}"", + ""domainName"": ""{eventMessage.DomainName}"", + ""secretId"": ""{eventMessage.SecretId}"", + ""projectId"": ""{eventMessage.ProjectId}"", + ""serviceAccountId"": ""{eventMessage.ServiceAccountId}"" + }} + }}"; + var expectedMessage = EventIntegrationHandlerTests.ExpectedMessage( + parsedJson + ); + + Assert.Single(_eventIntegrationPublisher.ReceivedCalls()); + await _eventIntegrationPublisher.Received(1) + .PublishAsync(Arg.Is(AssertHelper.AssertPropertyEqual(expectedMessage, new[] { "MessageId", "RenderedTemplate" }))); + + // compare renderedTemplate + var receivedCalls = _eventIntegrationPublisher.ReceivedCalls().ToList(); + Assert.Single(receivedCalls); + + var publishCall = receivedCalls.First(); + var actualMessage = publishCall.GetArguments()[0] as IntegrationMessage; + + Assert.NotNull(actualMessage); + Assert.True(JsonStringsAreEqual(expectedMessage.RenderedTemplate!, actualMessage.RenderedTemplate!), + $"Expected: {expectedMessage.RenderedTemplate}\nActual: {actualMessage.RenderedTemplate}"); + } + + private bool JsonStringsAreEqual(string expectedJson, string actualJson) + { + var expectedDoc = JsonNode.Parse(expectedJson); + var actualDoc = JsonNode.Parse(actualJson); + return JsonNode.DeepEquals(expectedDoc, actualDoc); + } }