From e816769f66672cc51712555bc1b6313ad1c55a20 Mon Sep 17 00:00:00 2001 From: jericho Date: Fri, 7 Jun 2024 10:15:46 -0400 Subject: [PATCH 1/7] Formatting --- Source/ZoomNet.UnitTests/Extensions/InternalTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/ZoomNet.UnitTests/Extensions/InternalTests.cs b/Source/ZoomNet.UnitTests/Extensions/InternalTests.cs index 52bc49d6..3cbeba08 100644 --- a/Source/ZoomNet.UnitTests/Extensions/InternalTests.cs +++ b/Source/ZoomNet.UnitTests/Extensions/InternalTests.cs @@ -178,11 +178,11 @@ public async Task ThrowsExceptionWhenExpectedRecordsAreMissing() { // Arrange var responseContent = @"{ - ""next_page_token"": """", - ""page_number"": 1, - ""page_size"": 100, - ""total_records"": 5 - }"; + ""next_page_token"": """", + ""page_number"": 1, + ""page_size"": 100, + ""total_records"": 5 + }"; var message = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(responseContent) From e6570362a5e10adef54866b8a0a67d1c636140ae Mon Sep 17 00:00:00 2001 From: jericho Date: Wed, 3 Jul 2024 09:37:17 -0400 Subject: [PATCH 2/7] Add a MockHttpMessageHandler parameter to the ZoomNet.UnitTests.Utils.GetFluentClient method in order to test scenarios where a request is retried after an expired token is refreshed --- Source/ZoomNet.UnitTests/Utils.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Source/ZoomNet.UnitTests/Utils.cs b/Source/ZoomNet.UnitTests/Utils.cs index 8b038da0..8d1f25b7 100644 --- a/Source/ZoomNet.UnitTests/Utils.cs +++ b/Source/ZoomNet.UnitTests/Utils.cs @@ -13,11 +13,12 @@ public static class Utils { private const string ZOOM_V2_BASE_URI = "https://api.zoom.us/v2"; - public static Pathoschild.Http.Client.IClient GetFluentClient(MockHttpMessageHandler httpMessageHandler) + public static Pathoschild.Http.Client.IClient GetFluentClient(MockHttpMessageHandler httpMessageHandler, MockHttpMessageHandler tokenMessageHandler = null) { - var httpClient = httpMessageHandler.ToHttpClient(); - var client = new FluentClient(new Uri(ZOOM_V2_BASE_URI), httpClient); - client.SetRequestCoordinator(new ZoomRetryCoordinator(new Http429RetryStrategy(), null)); + var client = new FluentClient(new Uri(ZOOM_V2_BASE_URI), httpMessageHandler.ToHttpClient()); + var tokenHandler = tokenMessageHandler == null ? null : new OAuthTokenHandler(OAuthConnectionInfo.ForServerToServer("bogus clientId", "bogus secret", "bogus accountId"), tokenMessageHandler.ToHttpClient(), null); + + client.SetRequestCoordinator(new ZoomRetryCoordinator(new Http429RetryStrategy(), tokenHandler)); client.Filters.Remove(); // Remove all the built-in formatters and replace them with our custom JSON formatter From 3696bcf04c6846ff242d2f8ba3cf99abfb992e86 Mon Sep 17 00:00:00 2001 From: jericho Date: Thu, 11 Jul 2024 10:31:04 -0400 Subject: [PATCH 3/7] (GH-349) Unit tests for WebhookParser.VerifySignature --- .../ZoomNet.UnitTests/WebhookParserTests.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Source/ZoomNet.UnitTests/WebhookParserTests.cs b/Source/ZoomNet.UnitTests/WebhookParserTests.cs index 59936bcb..f831657f 100644 --- a/Source/ZoomNet.UnitTests/WebhookParserTests.cs +++ b/Source/ZoomNet.UnitTests/WebhookParserTests.cs @@ -502,5 +502,44 @@ public void WebinarEnded() parsedEvent.Webinar.Password.ShouldBeNull(); parsedEvent.Webinar.Settings.ShouldBeNull(); } + + public class VerifySignature + { + [Fact] + public void Simple() + { + // Arange + var requestBody = "{\"payload\":{\"plainToken\":\"xys8n8PGS7mAU0m5-YJjRA\"},\"event_ts\":1720705455858,\"event\":\"endpoint.url_validation\"}"; + var secretToken = "4fv1RkqGQUq5sWbEz6hA5A"; + var signature = "v0=93a1a675965ceb9c5a50c5dfb31f20e50f763be37a54ef74cd2d16a1a8e5c0d6"; + var timestamp = "1720705455"; + + var parser = new WebhookParser(); + + // Act + var result = parser.VerifySignature(requestBody, secretToken, signature, timestamp); + + //Assert + result.ShouldBeTrue(); + } + + [Fact] + public void Topic_contains_non_ASCII_characters() + { + // Arange + var requestBody = "{\"event\":\"meeting.started\",\"payload\":{\"account_id\":\"VjZoEArIT5y-HlWxkV-tVA\",\"object\":{\"duration\":60,\"start_time\":\"2024-07-11T14:12:55Z\",\"timezone\":\"America/New_York\",\"topic\":\"Test \\uD83D\\uDE92\\uD83D\\uDE92 ? - ’ - – \\uD83D\\uDE97 HOLA\",\"id\":\"85393847045\",\"type\":2,\"uuid\":\"jUh5o3dKQIytvcsfTtKBlg==\",\"host_id\":\"8lzIwvZTSOqjndWPbPqzuA\"}},\"event_ts\":1720707175904}"; + var secretToken = "4fv1RkqGQUq5sWbEz6hA5A"; + var signature = "v0=1a14e79349318fa1bead50ebbd3c185ae078e182d3bbd30ab8010fcb7f4357c7"; + var timestamp = "1720707175"; + + var parser = new WebhookParser(); + + // Act + var result = parser.VerifySignature(requestBody, secretToken, signature, timestamp); + + //Assert + result.ShouldBeTrue(); + } + } } } From 9c27b743ff4c3021cd19b1be1692503c5c4d9a88 Mon Sep 17 00:00:00 2001 From: jericho Date: Thu, 11 Jul 2024 10:33:14 -0400 Subject: [PATCH 4/7] (GH-349) Switch from ASCII to UTF8 in WebhookParser.VerifySignature --- Source/ZoomNet/WebhookParser.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/ZoomNet/WebhookParser.cs b/Source/ZoomNet/WebhookParser.cs index 76d4d3b0..d80293c2 100644 --- a/Source/ZoomNet/WebhookParser.cs +++ b/Source/ZoomNet/WebhookParser.cs @@ -33,8 +33,9 @@ public bool VerifySignature(string requestBody, string secretToken, string signa var message = $"v0:{timestamp}:{requestBody}"; // Hash the message - var hmac = new HMACSHA256(Encoding.ASCII.GetBytes(secretToken)); - var hashAsBytes = hmac.ComputeHash(Encoding.ASCII.GetBytes(message)); + var hashingEncoding = Encoding.UTF8; // Switched from ASCII to UTF8 in July 2024. See https://github.com/Jericho/ZoomNet/issues/349 for more information. + var hmac = new HMACSHA256(hashingEncoding.GetBytes(secretToken)); + var hashAsBytes = hmac.ComputeHash(hashingEncoding.GetBytes(message)); var hashAsHex = hashAsBytes.ToHexString(); // Create the signature From 49ad2a16c6ba0bd87d4c5d4989858ea1a596c1cc Mon Sep 17 00:00:00 2001 From: jericho Date: Thu, 11 Jul 2024 19:31:55 -0400 Subject: [PATCH 5/7] Upgrade xUnit nuget packages --- Source/ZoomNet.UnitTests/ZoomNet.UnitTests.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/ZoomNet.UnitTests/ZoomNet.UnitTests.csproj b/Source/ZoomNet.UnitTests/ZoomNet.UnitTests.csproj index fb2e98c7..136ecd88 100644 --- a/Source/ZoomNet.UnitTests/ZoomNet.UnitTests.csproj +++ b/Source/ZoomNet.UnitTests/ZoomNet.UnitTests.csproj @@ -20,8 +20,8 @@ - - + + all runtime; build; native; contentfiles; analyzers From a98f5a42fe24e29197d1e61dccff330e4df93d18 Mon Sep 17 00:00:00 2001 From: jericho Date: Thu, 11 Jul 2024 19:43:38 -0400 Subject: [PATCH 6/7] Upgrade System.Text.Json Resolves #350 --- Source/ZoomNet/ZoomNet.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ZoomNet/ZoomNet.csproj b/Source/ZoomNet/ZoomNet.csproj index ead76ed5..2a9015d3 100644 --- a/Source/ZoomNet/ZoomNet.csproj +++ b/Source/ZoomNet/ZoomNet.csproj @@ -42,7 +42,7 @@ - + From 14ca8a3e29d7b7c9f02580f2ff67c4c9e4285726 Mon Sep 17 00:00:00 2001 From: jericho Date: Thu, 11 Jul 2024 19:50:33 -0400 Subject: [PATCH 7/7] Refresh build script --- build.cake | 18 ++++++++++-------- global.json | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/build.cake b/build.cake index cc5b3bc8..3befc266 100644 --- a/build.cake +++ b/build.cake @@ -1,13 +1,13 @@ // Install tools. #tool dotnet:?package=GitVersion.Tool&version=5.12.0 #tool dotnet:?package=coveralls.net&version=4.0.1 -#tool nuget:https://f.feedz.io/jericho/jericho/nuget/?package=GitReleaseManager&version=0.17.0-collaborators0004 -#tool nuget:?package=ReportGenerator&version=5.3.5 -#tool nuget:?package=xunit.runner.console&version=2.8.1 +#tool nuget:https://f.feedz.io/jericho/jericho/nuget/?package=GitReleaseManager&version=0.17.0-collaborators0007 +#tool nuget:?package=ReportGenerator&version=5.3.7 +#tool nuget:?package=xunit.runner.console&version=2.9.0 #tool nuget:?package=CodecovUploader&version=0.7.3 // Install addins. -#addin nuget:?package=Cake.Coveralls&version=1.1.0 +#addin nuget:?package=Cake.Coveralls&version=4.0.0 #addin nuget:?package=Cake.Git&version=4.0.0 #addin nuget:?package=Cake.Codecov&version=3.0.0 @@ -86,6 +86,8 @@ var isTagged = BuildSystem.AppVeyor.Environment.Repository.Tag.IsTag && !string. var isIntegrationTestsProjectPresent = FileExists(integrationTestsProject); var isUnitTestsProjectPresent = FileExists(unitTestsProject); var isBenchmarkProjectPresent = FileExists(benchmarkProject); +var removeIntegrationTests = isIntegrationTestsProjectPresent && (!isLocalBuild || target == "coverage"); +var removeBenchmarks = isBenchmarkProjectPresent && (!isLocalBuild || target == "coverage"); var publishingError = false; @@ -162,7 +164,7 @@ Setup(context => // Integration tests are intended to be used for debugging purposes and not intended to be executed in CI environment. // Also, the runner for these tests contains windows-specific code (such as resizing window, moving window to center of screen, etc.) // which can cause problems when attempting to run unit tests on an Ubuntu image on AppVeyor. - if (!isLocalBuild && isIntegrationTestsProjectPresent) + if (removeIntegrationTests) { Information(""); Information("Removing integration tests"); @@ -172,7 +174,7 @@ Setup(context => // Similarly, benchmarking can causes problems similar to this one: // error NETSDK1005: Assets file '/home/appveyor/projects/stronggrid/Source/StrongGrid.Benchmark/obj/project.assets.json' doesn't have a target for 'net5.0'. // Ensure that restore has run and that you have included 'net5.0' in the TargetFrameworks for your project. - if (!isLocalBuild && isBenchmarkProjectPresent) + if (removeBenchmarks) { Information(""); Information("Removing benchmark project"); @@ -182,7 +184,7 @@ Setup(context => Teardown(context => { - if (!isLocalBuild) + if (removeIntegrationTests || removeBenchmarks) { Information("Restoring projects that may have been removed during build script setup"); GitCheckout(".", new FilePath[] { solutionFile }); @@ -352,7 +354,7 @@ Task("Generate-Code-Coverage-Report") new FilePath(coverageFile), codeCoverageDir, new ReportGeneratorSettings() { - ClassFilters = new[] { "*.UnitTests*" } + ClassFilters = new[] { "+*" } } ); }); diff --git a/global.json b/global.json index d3edfcb3..175f404f 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.301", + "version": "8.0.303", "rollForward": "patch", "allowPrerelease": false }