From 87bba240b2fd88169b98bcf4878d6b00482f6c3c Mon Sep 17 00:00:00 2001 From: E M <5089238+emizzle@users.noreply.github.com> Date: Fri, 26 Jun 2026 16:43:04 +1000 Subject: [PATCH] feat: ignore whitespace in openapi hash Previously, whitespace deviations in openapi.yaml spec would cause a hash mismatch between the openapi.yaml in the Logos Storage image and the openapi.yaml in the project. This update removes whitespaces from the file contents before SHA256 hashing the contents. In addition, there were two independent Hash functions that were copies of each other to produce the same hash. This has been unified into a single FileHash utility. --- Framework/Utils/FileHash.cs | 24 +++++++++++++++++++ .../LogosStoragePluginPrebuild/Program.cs | 19 +++------------ ProjectPlugins/StoragePlugin/ApiChecker.cs | 10 ++++---- 3 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 Framework/Utils/FileHash.cs diff --git a/Framework/Utils/FileHash.cs b/Framework/Utils/FileHash.cs new file mode 100644 index 00000000..283f7470 --- /dev/null +++ b/Framework/Utils/FileHash.cs @@ -0,0 +1,24 @@ +using System.Security.Cryptography; +using System.Text; + +namespace Utils +{ + public static class FileHash + { + public static string HashContents(string fileContents) + { + var fileBytes = Encoding.ASCII.GetBytes(fileContents + .Replace(Environment.NewLine, "") + .Replace(" ", "")); // Ignore whitespace deviations in openapi.yaml + + var hash = SHA256.HashData(fileBytes); + return BitConverter.ToString(hash); + } + + public static string Hash(string filePath) + { + var file = File.ReadAllText(filePath); + return HashContents(file); + } + } +} diff --git a/ProjectPlugins/LogosStoragePluginPrebuild/Program.cs b/ProjectPlugins/LogosStoragePluginPrebuild/Program.cs index d8076a69..9eee995c 100644 --- a/ProjectPlugins/LogosStoragePluginPrebuild/Program.cs +++ b/ProjectPlugins/LogosStoragePluginPrebuild/Program.cs @@ -1,6 +1,4 @@ -using System.Security.Cryptography; -using System.Text; -using Utils; +using Utils; public static class Program { @@ -22,7 +20,7 @@ public static class Program // Force client rebuild by deleting previous artifact. File.Delete(clientFile); - var hash = CreateHash(openApiFile); + var hash = FileHash.Hash(openApiFile); // This hash is used to verify that the Codex docker image being used is compatible // with the openapi.yaml being used by the Codex plugin. // If the openapi.yaml files don't match, an exception is thrown. @@ -54,17 +52,6 @@ public static class Program return folder; } - private static string CreateHash(string openApiFile) - { - var file = File.ReadAllText(openApiFile); - var fileBytes = Encoding.ASCII.GetBytes(file - .Replace(Environment.NewLine, "")); - - var sha = SHA256.Create(); - var hash = sha.ComputeHash(fileBytes); - return BitConverter.ToString(hash); - } - private static void SearchAndInject(string hash, string targetFile) { var lines = File.ReadAllLines(targetFile); @@ -83,4 +70,4 @@ public static class Program } } } -} \ No newline at end of file +} diff --git a/ProjectPlugins/StoragePlugin/ApiChecker.cs b/ProjectPlugins/StoragePlugin/ApiChecker.cs index f20e760f..c1752ba3 100644 --- a/ProjectPlugins/StoragePlugin/ApiChecker.cs +++ b/ProjectPlugins/StoragePlugin/ApiChecker.cs @@ -10,7 +10,7 @@ namespace StoragePlugin public class ApiChecker { // - private const string OpenApiYamlHash = "79-88-91-C5-95-7A-C8-2B-2B-E6-14-1F-2D-02-E8-96-D3-D0-DC-65-97-C4-1D-9F-0F-B5-55-24-C1-43-2D-87"; + private const string OpenApiYamlHash = "F2-83-6E-23-8A-30-03-34-E8-24-52-B6-C3-00-21-5C-C0-3C-9C-5E-CB-CB-BF-68-47-7E-6A-87-D0-1F-46-8D"; private const string OpenApiFilePath = "/logosstorage/openapi.yaml"; private const string DisableEnvironmentVariable = "StoragePlugin_DISABLE_APICHECK"; @@ -55,9 +55,9 @@ namespace StoragePlugin var workflow = pluginTools.CreateWorkflow(); var container = containers.First().Containers.First(); - var containerApi = workflow.ExecuteCommand(container, "cat", OpenApiFilePath); + var openApiContents = workflow.ExecuteCommand(container, "cat", OpenApiFilePath); - if (string.IsNullOrEmpty(containerApi)) + if (string.IsNullOrEmpty(openApiContents)) { log.Error(Warning); @@ -65,7 +65,7 @@ namespace StoragePlugin return; } - var containerHash = Hash(containerApi); + var containerHash = FileHash.HashContents(openApiContents); if (containerHash == OpenApiYamlHash) { Log("API compatibility check passed."); @@ -73,7 +73,7 @@ namespace StoragePlugin return; } - OverwriteOpenApiYaml(containerApi); + OverwriteOpenApiYaml(openApiContents); log.Error(Failure); throw new Exception(Failure);