From 98cc346708923886e9d1708cf8158b66e13c515a Mon Sep 17 00:00:00 2001 From: jolov Date: Mon, 18 Nov 2024 16:50:51 -0800 Subject: [PATCH] Return correct `WebHook-Allowed-Origin` response header for CloudEvent schema subscriptions for gov cloud. --- .../CHANGELOG.md | 6 ++++ ....Azure.WebJobs.Extensions.EventGrid.csproj | 2 +- .../TriggerBinding/HttpRequestProcessor.cs | 26 +++++++++++++- .../tests/TestListener.cs | 34 +++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/CHANGELOG.md b/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/CHANGELOG.md index a190017629b4f..7a473d6b8397c 100644 --- a/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/CHANGELOG.md +++ b/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/CHANGELOG.md @@ -1,5 +1,11 @@ # Release History +## 3.4.4 (2024-11-19) + +### Bugs Fixed + +- Return correct `WebHook-Allowed-Origin` response header for CloudEvent schema subscriptions for gov cloud. + ## 3.4.3 (2024-09-10) ### Bugs Fixed diff --git a/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/src/Microsoft.Azure.WebJobs.Extensions.EventGrid.csproj b/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/src/Microsoft.Azure.WebJobs.Extensions.EventGrid.csproj index 4dbd98f779179..d812ab52af9da 100644 --- a/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/src/Microsoft.Azure.WebJobs.Extensions.EventGrid.csproj +++ b/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/src/Microsoft.Azure.WebJobs.Extensions.EventGrid.csproj @@ -2,7 +2,7 @@ $(RequiredTargetFrameworks) This extension adds bindings for EventGrid - 3.4.3 + 3.4.4 3.4.2 $(NoWarn);CS1591 diff --git a/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/src/TriggerBinding/HttpRequestProcessor.cs b/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/src/TriggerBinding/HttpRequestProcessor.cs index 3cbc1e2ce908f..827b84c15e81a 100644 --- a/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/src/TriggerBinding/HttpRequestProcessor.cs +++ b/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/src/TriggerBinding/HttpRequestProcessor.cs @@ -51,7 +51,7 @@ internal async Task ProcessAsync( }; } var response = new HttpResponseMessage(HttpStatusCode.OK); - response.Headers.Add("Webhook-Allowed-Origin", "eventgrid.azure.net"); + response.Headers.Add("Webhook-Allowed-Origin", GetAllowedOriginResponseHeader(req)); return response; } @@ -127,5 +127,29 @@ internal async Task ProcessAsync( new HttpResponseMessage(HttpStatusCode.Accepted) : new HttpResponseMessage(HttpStatusCode.BadRequest); } + + private static string GetAllowedOriginResponseHeader(HttpRequestMessage req) + { + const string publicCloudOrigin = "eventgrid.azure.net"; + const string requestOriginHeader = "WebHook-Request-Origin"; + + if (!req.Headers.Contains(requestOriginHeader)) + { + return publicCloudOrigin; + } + + string allowedOrigin = req.Headers.GetValues(requestOriginHeader).FirstOrDefault(); + switch (allowedOrigin) + { + case publicCloudOrigin: + case "eventgrid.azure.us": + case "eventgrid.azure.eaglex.ic.gov": + case "eventgrid.azure.microsoft.scloud": + case "eventgrid.azure.cn": + return allowedOrigin; + default: + return publicCloudOrigin; + } + } } } diff --git a/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/tests/TestListener.cs b/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/tests/TestListener.cs index 25673c6e713bc..8657d3a61476b 100644 --- a/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/tests/TestListener.cs +++ b/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/tests/TestListener.cs @@ -105,6 +105,40 @@ public async Task TestSubscribeOptions(string functionName) var request = new HttpRequestMessage(HttpMethod.Options, $"http://localhost/?functionName={functionName}"); var response = await ext.ConvertAsync(request, CancellationToken.None); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + // no WebHook-Request-Origin header, should fallback to public cloud + Assert.AreEqual("eventgrid.azure.net", response.Headers.GetValues("Webhook-Allowed-Origin").First()); + } + + [TestCase("eventgrid.azure.net")] + [TestCase("eventgrid.azure.us")] + [TestCase("eventgrid.azure.eaglex.ic.gov")] + [TestCase("eventgrid.azure.microsoft.scloud")] + [TestCase("eventgrid.azure.cn")] + public async Task TestSubscribeOptionsKnownAllowedOrigin(string origin) + { + using var host = TestHelpers.NewHost(CreateConfigProvider); + var ext = host.Services.GetServices().OfType().Single(); + await host.StartAsync(); // add listener + + var request = new HttpRequestMessage(HttpMethod.Options, $"http://localhost/?functionName=TestCloudEvent"); + request.Headers.Add("WebHook-Request-Origin", origin); + var response = await ext.ConvertAsync(request, CancellationToken.None); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + Assert.AreEqual(origin, response.Headers.GetValues("Webhook-Allowed-Origin").First()); + } + + [Test] + public async Task TestSubscribeOptionsUnknownAllowedOrigin() + { + using var host = TestHelpers.NewHost(CreateConfigProvider); + var ext = host.Services.GetServices().OfType().Single(); + await host.StartAsync(); // add listener + + var request = new HttpRequestMessage(HttpMethod.Options, $"http://localhost/?functionName=TestCloudEvent"); + request.Headers.Add("WebHook-Request-Origin", "someunknown.origin.com"); + var response = await ext.ConvertAsync(request, CancellationToken.None); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + // Unknown origin, should fallback to public cloud Assert.AreEqual("eventgrid.azure.net", response.Headers.GetValues("Webhook-Allowed-Origin").First()); }