From 57742ad871fe89ecaf17f3ffb8d1bb527ed9b3e5 Mon Sep 17 00:00:00 2001 From: Kukks Date: Wed, 20 Nov 2024 15:47:23 +0100 Subject: [PATCH 1/2] Do not throttle pos when logged in --- .../Controllers/UIPointOfSaleController.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs index 2e02a6d22..5a27a4f58 100644 --- a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs +++ b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs @@ -53,7 +53,9 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers UIInvoiceController invoiceController, FormDataService formDataService, IStringLocalizer stringLocalizer, - DisplayFormatter displayFormatter) + DisplayFormatter displayFormatter, + IRateLimitService rateLimitService, + IAuthorizationService authorizationService) { _currencies = currencies; _appService = appService; @@ -62,6 +64,8 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers _invoiceRepository = invoiceRepository; _invoiceController = invoiceController; _displayFormatter = displayFormatter; + _rateLimitService = rateLimitService; + _authorizationService = authorizationService; StringLocalizer = stringLocalizer; FormDataService = formDataService; } @@ -73,6 +77,8 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers private readonly AppService _appService; private readonly UIInvoiceController _invoiceController; private readonly DisplayFormatter _displayFormatter; + private readonly IRateLimitService _rateLimitService; + private readonly IAuthorizationService _authorizationService; public FormDataService FormDataService { get; } public IStringLocalizer StringLocalizer { get; } @@ -135,7 +141,6 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers [IgnoreAntiforgeryToken] [EnableCors(CorsPolicies.All)] [DomainMappingConstraint(PointOfSaleAppType.AppType)] - [RateLimitsFilter(ZoneLimits.PublicInvoices, Scope = RateLimitsScope.RemoteAddress)] [XFrameOptions(XFrameOptionsAttribute.XFrameOptions.Unset)] public async Task ViewPointOfSale(string appId, PosViewType? viewType = null, @@ -152,6 +157,12 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers string formResponse = null, CancellationToken cancellationToken = default) { + if (!(await _authorizationService.AuthorizeAsync(HttpContext.User, appId, Policies.CanViewInvoices)).Succeeded && + !await _rateLimitService.Throttle(ZoneLimits.PublicInvoices, HttpContext.Connection.RemoteIpAddress.ToString(), HttpContext.RequestAborted)) + { + return new TooManyRequestsResult(ZoneLimits.PublicInvoices); + } + var app = await _appService.GetApp(appId, PointOfSaleAppType.AppType); // not allowing negative tips or discounts From 7da247ffd6f09d57dcf643c2c76e3625e3198b43 Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Mon, 9 Dec 2024 09:28:50 +0900 Subject: [PATCH 2/2] Fix test --- BTCPayServer.Tests/SeleniumTests.cs | 1 - .../Controllers/UIPointOfSaleController.cs | 32 +++++++++++-------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index fad621877..dbc981e09 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -95,7 +95,6 @@ namespace BTCPayServer.Tests s.Driver.FindElement(By.CssSelector("button[type='submit']")).Click(); - Assert.Contains("Enter your email", s.Driver.PageSource); s.Driver.FindElement(By.Name("buyerEmail")).SendKeys("aa@aa.com"); s.Driver.FindElement(By.CssSelector("input[type='submit']")).Click(); diff --git a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs index 5a27a4f58..37fdd33d9 100644 --- a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs +++ b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs @@ -157,12 +157,9 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers string formResponse = null, CancellationToken cancellationToken = default) { - if (!(await _authorizationService.AuthorizeAsync(HttpContext.User, appId, Policies.CanViewInvoices)).Succeeded && - !await _rateLimitService.Throttle(ZoneLimits.PublicInvoices, HttpContext.Connection.RemoteIpAddress.ToString(), HttpContext.RequestAborted)) - { + if (await Throttle(appId)) return new TooManyRequestsResult(ZoneLimits.PublicInvoices); - } - + var app = await _appService.GetApp(appId, PointOfSaleAppType.AppType); // not allowing negative tips or discounts @@ -174,7 +171,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers if (app == null) return NotFound(); - + var settings = app.GetSettings(); settings.DefaultView = settings.EnableShoppingCart ? PosViewType.Cart : settings.DefaultView; var currentView = viewType ?? settings.DefaultView; @@ -247,7 +244,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers var expectedCartItemPrice = itemChoice.PriceType != AppItemPriceType.Topup ? itemChoice.Price ?? 0 : 0; - + if (cartItem.Price < expectedCartItemPrice) cartItem.Price = expectedCartItemPrice; @@ -256,7 +253,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers if (customAmount is { } c) price += c; if (discount is { } d) - price -= price * d/100.0m; + price -= price * d / 100.0m; if (tip is { } t) price += t; } @@ -277,7 +274,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers { var vm = new PostRedirectViewModel { - FormUrl = Url.Action(nameof(POSForm), "UIPointOfSale", new {appId, buyerEmail = email}), + FormUrl = Url.Action(nameof(POSForm), "UIPointOfSale", new { appId, buyerEmail = email }), FormParameters = new MultiValueDictionary(Request.Form.Select(pair => new KeyValuePair>(pair.Key, pair.Value))) }; @@ -314,7 +311,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers amtField.Value = price?.ToString(); } formResponseJObject = FormDataService.GetValues(form); - + var invoiceRequest = FormDataService.GenerateInvoiceParametersFromForm(form); if (invoiceRequest.Amount is not null) { @@ -343,7 +340,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers : Request.GetAbsoluteUri(Url.Action(nameof(ViewPointOfSale), "UIPointOfSale", new { appId, viewType })), PaymentMethods = paymentMethods?.Where(p => p.Value.Enabled).Select(p => p.Key).ToArray() }, - AdditionalSearchTerms = new [] { AppService.GetAppSearchTerm(app) } + AdditionalSearchTerms = new[] { AppService.GetAppSearchTerm(app) } }, store, HttpContext.Request.GetAbsoluteRoot(), new List { AppService.GetAppInternalTag(appId) }, cancellationToken, entity => @@ -358,7 +355,8 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers if (choice is not null) { var dict = new Dictionary { { "Title", choice.Title } }; - if (!string.IsNullOrEmpty(choice.Description)) dict["Description"] = choice.Description; + if (!string.IsNullOrEmpty(choice.Description)) + dict["Description"] = choice.Description; receiptData = JObject.FromObject(dict); } else if (jposData is not null) @@ -374,7 +372,8 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers var cartData = new JObject(); foreach (PosCartItem cartItem in posCartItems) { - if (!selectedChoices.TryGetValue(cartItem.Id, out var selectedChoice)) continue; + if (!selectedChoices.TryGetValue(cartItem.Id, out var selectedChoice)) + continue; var singlePrice = _displayFormatter.Currency(cartItem.Price, settings.Currency, DisplayFormatter.CurrencyFormat.Symbol); var totalPrice = _displayFormatter.Currency(cartItem.Price * cartItem.Count, settings.Currency, DisplayFormatter.CurrencyFormat.Symbol); var ident = selectedChoice.Title ?? selectedChoice.Id; @@ -386,7 +385,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers { for (var i = 0; i < amountsArray.Count; i++) { - cartData.Add($"Custom Amount {i+1}", _displayFormatter.Currency(amountsArray[i].ToObject(), settings.Currency, DisplayFormatter.CurrencyFormat.Symbol)); + cartData.Add($"Custom Amount {i + 1}", _displayFormatter.Currency(amountsArray[i].ToObject(), settings.Currency, DisplayFormatter.CurrencyFormat.Symbol)); } } receiptData.Add("Cart", cartData); @@ -430,6 +429,11 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers } } + private async Task Throttle(string appId) => + !(await _authorizationService.AuthorizeAsync(HttpContext.User, appId, Policies.CanViewInvoices)).Succeeded && + HttpContext.Connection?.RemoteIpAddress is not null && + !await _rateLimitService.Throttle(ZoneLimits.PublicInvoices, HttpContext.Connection.RemoteIpAddress.ToString(), HttpContext.RequestAborted); + private JObject TryParseJObject(string posData) { try