From b88f9faba0aef660a9b31db327b6b1dfb6181a4e Mon Sep 17 00:00:00 2001 From: Lorenz Cuno Klopfenstein Date: Tue, 4 Feb 2025 01:48:08 +0100 Subject: [PATCH 1/4] POS ID verification in payload --- src/ApiServer/ApiServer/ControllerExtensions.cs | 2 +- src/ApiServer/ApiServer/Controllers/PaymentController.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ApiServer/ApiServer/ControllerExtensions.cs b/src/ApiServer/ApiServer/ControllerExtensions.cs index d9daed3..af2b2b2 100644 --- a/src/ApiServer/ApiServer/ControllerExtensions.cs +++ b/src/ApiServer/ApiServer/ControllerExtensions.cs @@ -88,7 +88,7 @@ public static ActionResult OtcNotFound(this ControllerBase c) { public static ActionResult PayloadVerificationFailure(this ControllerBase c, string title = null) { return new ObjectResult( new ProblemDetails { - Status = StatusCodes.Status403Forbidden, + Status = StatusCodes.Status422UnprocessableEntity, // See https://httpstatuses.com/422 Type = "https://wom.social/api/problems/payload-verification-failure", Title = title ?? "Failed to verify request contents" } diff --git a/src/ApiServer/ApiServer/Controllers/PaymentController.cs b/src/ApiServer/ApiServer/Controllers/PaymentController.cs index 33e32b4..165cc07 100644 --- a/src/ApiServer/ApiServer/Controllers/PaymentController.cs +++ b/src/ApiServer/ApiServer/Controllers/PaymentController.cs @@ -287,8 +287,8 @@ [FromBody] PaymentStatusPayload payload } if(payload.PosId != payloadContent.PosId) { - Logger.LogError(LoggingEvents.PaymentStatus, "POS ID mismatch in payload ({0} != {1})", payload.PosId, payloadContent.PosId); - return BadRequest(); + Logger.LogError(LoggingEvents.PaymentStatus, "Verification failed, POS ID {0} differs from ID {1} in payload", payload.PosId, payloadContent.PosId); + return this.PayloadVerificationFailure("Verification of POS ID in payload failed"); } try { @@ -297,8 +297,8 @@ [FromBody] PaymentStatusPayload payload Logger.LogInformation("Payment {0} not found", payloadContent.Otc); return this.OtcNotFound(); } - if(payment.PosId != payment.PosId) { - Logger.LogWarning(LoggingEvents.PaymentStatus, "Payment {0} has not been created by POS {1}", payment.Otc, payment.PosId); + if(!payment.PosId.Equals(payload.PosId)) { + Logger.LogWarning(LoggingEvents.PaymentStatus, "Payment {0} has not been created by POS {1}", payment.Otc, payload.PosId); return this.OtcNotFound(); } From 2bfdd03e7599a480dc25b809eac68d6f614b9b48 Mon Sep 17 00:00:00 2001 From: Lorenz Cuno Klopfenstein Date: Tue, 4 Feb 2025 02:10:10 +0100 Subject: [PATCH 2/4] Fix equality operator --- src/ApiServer/ApiServer/Controllers/PaymentController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ApiServer/ApiServer/Controllers/PaymentController.cs b/src/ApiServer/ApiServer/Controllers/PaymentController.cs index 165cc07..c41f2f2 100644 --- a/src/ApiServer/ApiServer/Controllers/PaymentController.cs +++ b/src/ApiServer/ApiServer/Controllers/PaymentController.cs @@ -297,7 +297,7 @@ [FromBody] PaymentStatusPayload payload Logger.LogInformation("Payment {0} not found", payloadContent.Otc); return this.OtcNotFound(); } - if(!payment.PosId.Equals(payload.PosId)) { + if(!payload.PosId.Equals(payment.PosId)) { Logger.LogWarning(LoggingEvents.PaymentStatus, "Payment {0} has not been created by POS {1}", payment.Otc, payload.PosId); return this.OtcNotFound(); } From b139ff508f0965f5eec1e73110d1b64b3b27851d Mon Sep 17 00:00:00 2001 From: Lorenz Cuno Klopfenstein Date: Tue, 4 Feb 2025 02:25:04 +0100 Subject: [PATCH 3/4] Log fixes --- .../ApiServer/Controllers/PaymentController.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ApiServer/ApiServer/Controllers/PaymentController.cs b/src/ApiServer/ApiServer/Controllers/PaymentController.cs index c41f2f2..30d2ecc 100644 --- a/src/ApiServer/ApiServer/Controllers/PaymentController.cs +++ b/src/ApiServer/ApiServer/Controllers/PaymentController.cs @@ -287,37 +287,37 @@ [FromBody] PaymentStatusPayload payload } if(payload.PosId != payloadContent.PosId) { - Logger.LogError(LoggingEvents.PaymentStatus, "Verification failed, POS ID {0} differs from ID {1} in payload", payload.PosId, payloadContent.PosId); + Logger.LogError($"Verification failed, POS ID {payload.PosId} differs from ID {payloadContent.PosId} in payload"); return this.PayloadVerificationFailure("Verification of POS ID in payload failed"); } try { var payment = await PaymentService.GetPaymentRequestByOtc(payloadContent.Otc); if(payment == null) { - Logger.LogInformation("Payment {0} not found", payloadContent.Otc); + Logger.LogInformation(LoggingEvents.PaymentStatus, $"Payment {payloadContent.Otc} not found"); return this.OtcNotFound(); } if(!payload.PosId.Equals(payment.PosId)) { - Logger.LogWarning(LoggingEvents.PaymentStatus, "Payment {0} has not been created by POS {1}", payment.Otc, payload.PosId); + Logger.LogWarning(LoggingEvents.PaymentStatus, $"Payment {payment.Otc} by POS {payment.PosId} was not created by POS specified in request ({payload.PosId})"); return this.OtcNotFound(); } var pos = await PosService.GetPosById(payment.PosId); if(pos == null) { - Logger.LogWarning(LoggingEvents.PaymentStatus, "POS of payment {0} does not exist", payment.Otc); + Logger.LogWarning(LoggingEvents.PaymentStatus, $"POS of payment {payment.Otc} does not exist"); return this.PosNotFound(); } var posPublicKey = CryptoHelper.LoadKeyFromString(pos.PublicKey); - Logger.LogInformation(LoggingEvents.PaymentStatus, "Retrieved status of payment {0}", payloadContent.Otc); + Logger.LogInformation(LoggingEvents.PaymentStatus, $"Retrieved status of payment {payloadContent.Otc}"); return Ok(new PaymentStatusResponse { PosId = payload.PosId, Payload = Crypto.Encrypt(new PaymentStatusResponse.Content { Persistent = payment.IsPersistent, - HasBeenPerformed = (payment.Confirmations != null && payment.Confirmations.Count > 0), - Confirmations = (from c in payment.Confirmations ?? new() + HasBeenPerformed = payment.Confirmations != null && payment.Confirmations.Count > 0, + Confirmations = (from c in payment.Confirmations ?? [] select new PaymentStatusResponse.Confirmation { PerformedAt = DateTime.SpecifyKind(c.PerformedAt, DateTimeKind.Utc) }).ToList(), From c521aeeab14a3dc094601c0ee9405442a090ebf9 Mon Sep 17 00:00:00 2001 From: Lorenz Cuno Klopfenstein Date: Tue, 4 Feb 2025 02:35:05 +0100 Subject: [PATCH 4/4] Fix ObjectId equality check --- src/ApiServer/ApiServer/Controllers/PaymentController.cs | 2 +- src/ApiServer/ApiServer/IdentifierExtension.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ApiServer/ApiServer/Controllers/PaymentController.cs b/src/ApiServer/ApiServer/Controllers/PaymentController.cs index 30d2ecc..e1721cd 100644 --- a/src/ApiServer/ApiServer/Controllers/PaymentController.cs +++ b/src/ApiServer/ApiServer/Controllers/PaymentController.cs @@ -297,7 +297,7 @@ [FromBody] PaymentStatusPayload payload Logger.LogInformation(LoggingEvents.PaymentStatus, $"Payment {payloadContent.Otc} not found"); return this.OtcNotFound(); } - if(!payload.PosId.Equals(payment.PosId)) { + if(!payload.PosId.Matches(payment.PosId)) { Logger.LogWarning(LoggingEvents.PaymentStatus, $"Payment {payment.Otc} by POS {payment.PosId} was not created by POS specified in request ({payload.PosId})"); return this.OtcNotFound(); } diff --git a/src/ApiServer/ApiServer/IdentifierExtension.cs b/src/ApiServer/ApiServer/IdentifierExtension.cs index 03cb206..14b01ed 100644 --- a/src/ApiServer/ApiServer/IdentifierExtension.cs +++ b/src/ApiServer/ApiServer/IdentifierExtension.cs @@ -6,7 +6,7 @@ namespace WomPlatform.Web.Api { public static class IdentifierExtension { - public static bool Equals(this Identifier id, ObjectId objId) { + public static bool Matches(this Identifier id, ObjectId objId) { return string.Equals(id.Id, objId.ToString(), StringComparison.InvariantCulture); }