From 8bea3dd21eeaf94980b4d497d899c3fc939af645 Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Mon, 10 Jan 2022 22:10:04 +0900 Subject: [PATCH] [Greenfield] if some json property are invalid, throw nice error instead of an exception (fix #2795) --- BTCPayServer.Client/BTCPayServerClient.cs | 8 +++++++- BTCPayServer.Tests/GreenfieldAPITests.cs | 3 +++ BTCPayServer/Filters/JsonObjectExceptionFilter.cs | 2 +- BTCPayServer/Hosting/Startup.cs | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/BTCPayServer.Client/BTCPayServerClient.cs b/BTCPayServer.Client/BTCPayServerClient.cs index 0fa8a0658..eaab2612f 100644 --- a/BTCPayServer.Client/BTCPayServerClient.cs +++ b/BTCPayServer.Client/BTCPayServerClient.cs @@ -18,7 +18,6 @@ namespace BTCPayServer.Client private readonly string _username; private readonly string _password; private readonly HttpClient _httpClient; - public Uri Host => _btcpayHost; public string APIKey => _apiKey; @@ -84,6 +83,13 @@ namespace BTCPayServer.Client using var resp = await _httpClient.SendAsync(CreateHttpRequest(path, queryPayload, method), cancellationToken); return await HandleResponse(resp); } + public async Task SendHttpRequest(string path, + object bodyPayload = null, + HttpMethod method = null, CancellationToken cancellationToken = default) + { + using var resp = await _httpClient.SendAsync(CreateHttpRequest(path: path, bodyPayload: bodyPayload, method: method), cancellationToken); + return await HandleResponse(resp); + } protected virtual HttpRequestMessage CreateHttpRequest(string path, Dictionary queryPayload = null, HttpMethod method = null) diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs index fce9f3449..c18accd75 100644 --- a/BTCPayServer.Tests/GreenfieldAPITests.cs +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -1592,6 +1592,9 @@ namespace BTCPayServer.Tests Assert.Equal(firstAddress, (await viewOnlyClient.PreviewProposedStoreOnChainPaymentMethodAddresses(store.Id, "BTC", new UpdateOnChainPaymentMethodRequest() { Enabled = true, DerivationScheme = xpub })).Addresses.First().Address); + await AssertValidationError(new[] { "accountKeyPath" }, () => viewOnlyClient.SendHttpRequest(path: $"api/v1/stores/{store.Id}/payment-methods/Onchain/BTC/preview", method: HttpMethod.Post, + bodyPayload: JObject.Parse("{\"accountKeyPath\": \"0/1\"}"))); + var method = await client.UpdateStoreOnChainPaymentMethod(store.Id, "BTC", new UpdateOnChainPaymentMethodRequest() { Enabled = true, DerivationScheme = xpub }); diff --git a/BTCPayServer/Filters/JsonObjectExceptionFilter.cs b/BTCPayServer/Filters/JsonObjectExceptionFilter.cs index 66f1171b9..462760613 100644 --- a/BTCPayServer/Filters/JsonObjectExceptionFilter.cs +++ b/BTCPayServer/Filters/JsonObjectExceptionFilter.cs @@ -14,7 +14,7 @@ namespace BTCPayServer.Filters { if (context.Exception is NBitcoin.JsonConverters.JsonObjectException jsonObject) { - context.Result = new ObjectResult(new GreenfieldValidationError(jsonObject.Path, jsonObject.Message)) { StatusCode = 400 }; + context.Result = new ObjectResult(new[] { new GreenfieldValidationError(jsonObject.Path, jsonObject.Message) }) { StatusCode = 422 }; context.ExceptionHandled = true; } } diff --git a/BTCPayServer/Hosting/Startup.cs b/BTCPayServer/Hosting/Startup.cs index 23ff4d249..65daa8ae1 100644 --- a/BTCPayServer/Hosting/Startup.cs +++ b/BTCPayServer/Hosting/Startup.cs @@ -122,6 +122,7 @@ namespace BTCPayServer.Hosting if (!Configuration.GetOrDefault("nocsp", false)) o.Filters.Add(new ContentSecurityPolicyAttribute(CSPTemplate.AntiXSS)); o.Filters.Add(new JsonHttpExceptionFilter()); + o.Filters.Add(new JsonObjectExceptionFilter()); }) .ConfigureApiBehaviorOptions(options => {