From 75a6d2f62026e180747e7c4448c0507b7b4b46c6 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Thu, 22 Feb 2024 11:33:23 +0100 Subject: [PATCH] Add endppoint for creating package hashes --- .../API/Endpoints/VerificationEndpointsV1.cs | 7 +++- .../API/Handlers/VerificationHandlers.cs | 37 +++++++++++++++++-- src/PackageRegistryService/OpenAPI/DocGen.cs | 2 +- .../OpenAPI/OperationMetadataProcessor.cs | 14 +++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/PackageRegistryService/API/Endpoints/VerificationEndpointsV1.cs b/src/PackageRegistryService/API/Endpoints/VerificationEndpointsV1.cs index 4908018..6c62c4c 100644 --- a/src/PackageRegistryService/API/Endpoints/VerificationEndpointsV1.cs +++ b/src/PackageRegistryService/API/Endpoints/VerificationEndpointsV1.cs @@ -9,7 +9,12 @@ public static RouteGroupBuilder MapVerificationApiV1(this RouteGroupBuilder grou { group.MapPost("/", VerificationHandlers.Verify) .WithOpenApi() - .WithName("Verify"); + .WithName("VerifyPackageContent"); + + group.MapPost("/hashes", VerificationHandlers.CreateContentHash) + .WithOpenApi() + .WithName("CreatePackageContentHash") + .AddEndpointFilter(); // creating hashes via post requests requires an API key return group.WithTags("Content Verification"); } diff --git a/src/PackageRegistryService/API/Handlers/VerificationHandlers.cs b/src/PackageRegistryService/API/Handlers/VerificationHandlers.cs index 153fdf7..b5e193a 100644 --- a/src/PackageRegistryService/API/Handlers/VerificationHandlers.cs +++ b/src/PackageRegistryService/API/Handlers/VerificationHandlers.cs @@ -9,7 +9,7 @@ public class VerificationHandlers { public static async Task> Verify(PackageContentHash hashedPackage, ValidationPackageDb database) { - var package = await + var existingHash = await database.Hashes.FindAsync( hashedPackage.PackageName, hashedPackage.PackageMajorVersion, @@ -17,17 +17,48 @@ public static async Task> Verify(Pack hashedPackage.PackagePatchVersion ); - if (package is null) + var existingPackage = await + database.ValidationPackages.FindAsync( + hashedPackage.PackageName, + hashedPackage.PackageMajorVersion, + hashedPackage.PackageMinorVersion, + hashedPackage.PackagePatchVersion + ); + + if (existingHash is null || existingPackage is null) { return TypedResults.NotFound(); } - if (package.Hash != hashedPackage.Hash) + if (existingHash.Hash != hashedPackage.Hash) { return TypedResults.UnprocessableEntity(); } return TypedResults.Ok(); } + + public static async Task, Conflict, UnauthorizedHttpResult>> CreateContentHash(PackageContentHash hashedPackage, ValidationPackageDb database) + { + + var existing = await + database.Hashes.FindAsync( + hashedPackage.PackageName, + hashedPackage.PackageMajorVersion, + hashedPackage.PackageMinorVersion, + hashedPackage.PackagePatchVersion + ); + + if (existing != null) + { + return TypedResults.Conflict(); + } + + database.Hashes.Add(hashedPackage); + await database.SaveChangesAsync(); + + return TypedResults.Ok(hashedPackage); + + } } } diff --git a/src/PackageRegistryService/OpenAPI/DocGen.cs b/src/PackageRegistryService/OpenAPI/DocGen.cs index e5799d9..145b705 100644 --- a/src/PackageRegistryService/OpenAPI/DocGen.cs +++ b/src/PackageRegistryService/OpenAPI/DocGen.cs @@ -27,7 +27,7 @@ public static void GeneratorSetup (AspNetCoreOpenApiDocumentGeneratorSettings se // For e.g. JWT, this would work because we could rely on full blown authorization service/config, but this is a simple API key checked via endpoint filters settings.OperationProcessors.Add( new OperationSecurityProcessor( - secureEndpointIds: ["CreatePackage"] + secureEndpointIds: ["CreatePackage", "CreatePackageContentHash"] ) ); // fix for WithDescription and WithSummary methods not working with nswag and minimal API endpoints diff --git a/src/PackageRegistryService/OpenAPI/OperationMetadataProcessor.cs b/src/PackageRegistryService/OpenAPI/OperationMetadataProcessor.cs index 9b95dd7..cf2e1f1 100644 --- a/src/PackageRegistryService/OpenAPI/OperationMetadataProcessor.cs +++ b/src/PackageRegistryService/OpenAPI/OperationMetadataProcessor.cs @@ -35,6 +35,20 @@ public class OperationMetadataProcessor : IOperationProcessor { "Summary", "Get a specific version of a validation package" }, { "Description", "Get a specific version of a validation package from the package registry. Package content is a base64 encoded byte array containing the package executable." } } + }, + { + "VerifyPackageContent", new Dictionary + { + { "Summary", "Verify a content hash for a given package." }, + { "Description", "Verify a content hash for a given package. Hashes are MD5 hex fingerprints." } + } + }, + { + "CreatePackageContentHash", new Dictionary + { + { "Summary", "Create a content hash for a given package." }, + { "Description", "Create a content hash for a given package. Hashes are MD5 hex fingerprints. This Endpoint requires API Key authentication." } + } } };