diff --git a/src/ApiService/ApiService/onefuzzlib/Events.cs b/src/ApiService/ApiService/onefuzzlib/Events.cs index 544270dff0..395034ec7d 100644 --- a/src/ApiService/ApiService/onefuzzlib/Events.cs +++ b/src/ApiService/ApiService/onefuzzlib/Events.cs @@ -38,6 +38,7 @@ public class Events : IEvents { private readonly IContainers _containers; private readonly ICreds _creds; private readonly JsonSerializerOptions _options; + private readonly JsonSerializerOptions _deserializingFromBlobOptions; public Events(ILogTracer log, IOnefuzzContext context) { _queue = context.Queue; @@ -49,6 +50,9 @@ public Events(ILogTracer log, IOnefuzzContext context) { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; _options.Converters.Add(new RemoveUserInfo()); + _deserializingFromBlobOptions = new JsonSerializerOptions(EntityConverter.GetJsonSerializerOptions()) { + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + }; } public virtual async Async.Task QueueSignalrEvent(DownloadableEventMessage message) { @@ -96,7 +100,7 @@ public async Async.Task> GetEvent(Guid eventId) { return OneFuzzResult.Error(ErrorCode.UNABLE_TO_FIND, $"Could not find container for event with id {eventId}"); } - var eventMessage = JsonSerializer.Deserialize(blob, _options); + var eventMessage = JsonSerializer.Deserialize(blob, _deserializingFromBlobOptions); if (eventMessage == null) { return OneFuzzResult.Error(ErrorCode.UNEXPECTED_DATA_SHAPE, $"Could not deserialize event with id {eventId}"); } diff --git a/src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs b/src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs index 291f66a398..8635fb6ce9 100644 --- a/src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs +++ b/src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs @@ -13,6 +13,8 @@ public interface IWebhookOperations : IOrm { Async.Task GetByWebhookId(Guid webhookId); Async.Task Send(WebhookMessageLog messageLog); Task Ping(Webhook webhook); + Task>> BuildMessage(Guid webhookId, Guid eventId, EventType eventType, BaseEvent webhookEvent, String? secretToken, WebhookMessageFormat? messageFormat); + } public class WebhookOperations : Orm, IWebhookOperations { diff --git a/src/ApiService/IntegrationTests/EventsTests.cs b/src/ApiService/IntegrationTests/EventsTests.cs index b32c43bcdb..7f9d4b11f0 100644 --- a/src/ApiService/IntegrationTests/EventsTests.cs +++ b/src/ApiService/IntegrationTests/EventsTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net; using Azure.Storage.Blobs; using FluentAssertions; @@ -62,4 +63,52 @@ public async Async.Task BlobIsCreatedAndIsAccessible() { var eventData = await sr.ReadToEndAsync(); // read to make sure the SAS URL works eventData.Should().Contain(ping.PingId.ToString()); } + + [Fact] + public async Async.Task UserInfoIsDeserialized() { + var jobId = Guid.NewGuid(); + var taskId = Guid.NewGuid(); + var taskConfig = new TaskConfig( + jobId, + null, + new TaskDetails( + TaskType.Coverage, + 1 + ) + ); + var webhookId = Guid.NewGuid(); + var webhookName = "test-webhook"; + var appId = Guid.NewGuid(); + var objectId = Guid.NewGuid(); + var upn = Guid.NewGuid().ToString(); + + var insertWebhook = await Context.WebhookOperations.Insert( + new Webhook(webhookId, webhookName, null, new List { EventType.TaskStopped }, null, WebhookMessageFormat.Onefuzz) + ); + insertWebhook.IsOk.Should().BeTrue(); + + await Context.Events.SendEvent(new EventTaskStopped( + jobId, + taskId, + new UserInfo( + appId, + objectId, + upn + ), + taskConfig + )); + + var webhookMessageLog = await Context.WebhookMessageLogOperations.SearchAll() + .FirstAsync(wml => wml.WebhookId == webhookId && wml.EventType == EventType.TaskStopped); + + webhookMessageLog.Should().NotBeNull(); + + var message = await Context.WebhookOperations.BuildMessage(webhookMessageLog.WebhookId, webhookMessageLog.EventId, webhookMessageLog.EventType, webhookMessageLog.Event, null, WebhookMessageFormat.Onefuzz); + + message.IsOk.Should().BeTrue(); + var eventPayload = message.OkV!.Item1; + + eventPayload.Should() + .ContainAll(jobId.ToString(), taskId.ToString()); + } }