From 15e73e1cad1687eff3342a95c1bad731fc16d34f Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Fri, 13 Oct 2017 17:46:19 +0900 Subject: [PATCH] Properly limit CORS to bitpay api --- .../Controllers/InvoiceController.API.cs | 27 +++++++++++++++---- .../Controllers/InvoiceController.UI.cs | 4 +-- BTCPayServer/Controllers/InvoiceController.cs | 7 ++--- BTCPayServer/Hosting/BTCPayServerServices.cs | 1 + BTCPayServer/Hosting/Startup.cs | 13 +++++---- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/BTCPayServer/Controllers/InvoiceController.API.cs b/BTCPayServer/Controllers/InvoiceController.API.cs index 4ba230a1d..00d750e87 100644 --- a/BTCPayServer/Controllers/InvoiceController.API.cs +++ b/BTCPayServer/Controllers/InvoiceController.API.cs @@ -11,25 +11,43 @@ using System.Linq; using System.Threading.Tasks; using BTCPayServer.Data; using BTCPayServer.Servcices.Invoices; +using Microsoft.AspNetCore.Cors; +using BTCPayServer.Services.Stores; namespace BTCPayServer.Controllers { - public partial class InvoiceController + [EnableCors("BitpayAPI")] + [BitpayAPIConstraint] + public class InvoiceControllerAPI : Controller { + private InvoiceController _InvoiceController; + private InvoiceRepository _InvoiceRepository; + private TokenRepository _TokenRepository; + private StoreRepository _StoreRepository; + + public InvoiceControllerAPI(InvoiceController invoiceController, + InvoiceRepository invoceRepository, + TokenRepository tokenRepository, + StoreRepository storeRepository) + { + this._InvoiceController = invoiceController; + this._InvoiceRepository = invoceRepository; + this._TokenRepository = tokenRepository; + this._StoreRepository = storeRepository; + } + [HttpPost] [Route("invoices")] [MediaTypeConstraint("application/json")] - [BitpayAPIConstraint] public async Task> CreateInvoice([FromBody] Invoice invoice) { var bitToken = await CheckTokenPermissionAsync(Facade.Merchant, invoice.Token); var store = await FindStore(bitToken); - return await CreateInvoiceCore(invoice, store); + return await _InvoiceController.CreateInvoiceCore(invoice, store, HttpContext.Request.GetAbsoluteRoot()); } [HttpGet] [Route("invoices/{id}")] - [BitpayAPIConstraint] public async Task> GetInvoice(string id, string token) { var bitToken = await CheckTokenPermissionAsync(Facade.Merchant, token); @@ -44,7 +62,6 @@ namespace BTCPayServer.Controllers [HttpGet] [Route("invoices")] - [BitpayAPIConstraint] public async Task> GetInvoices( string token, DateTimeOffset? dateStart = null, diff --git a/BTCPayServer/Controllers/InvoiceController.UI.cs b/BTCPayServer/Controllers/InvoiceController.UI.cs index 303c4fd76..9b8110643 100644 --- a/BTCPayServer/Controllers/InvoiceController.UI.cs +++ b/BTCPayServer/Controllers/InvoiceController.UI.cs @@ -150,7 +150,6 @@ namespace BTCPayServer.Controllers [HttpGet] [Route("i/{invoiceId}/status")] - [DisableCors] public async Task GetStatus(string invoiceId) { var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId); @@ -161,7 +160,6 @@ namespace BTCPayServer.Controllers [HttpPost] [Route("i/{invoiceId}/UpdateCustomer")] - [DisableCors] public async Task UpdateCustomer(string invoiceId, [FromBody]UpdateCustomerModel data) { if(!ModelState.IsValid) @@ -248,7 +246,7 @@ namespace BTCPayServer.Controllers ItemDesc = model.ItemDesc, FullNotifications = true, BuyerEmail = model.BuyerEmail, - }, store); + }, store, HttpContext.Request.GetAbsoluteRoot()); StatusMessage = $"Invoice {result.Data.Id} just created!"; return RedirectToAction(nameof(ListInvoices)); diff --git a/BTCPayServer/Controllers/InvoiceController.cs b/BTCPayServer/Controllers/InvoiceController.cs index 171c17de5..67abb5fec 100644 --- a/BTCPayServer/Controllers/InvoiceController.cs +++ b/BTCPayServer/Controllers/InvoiceController.cs @@ -43,7 +43,6 @@ namespace BTCPayServer.Controllers { public partial class InvoiceController : Controller { - TokenRepository _TokenRepository; InvoiceRepository _InvoiceRepository; BTCPayWallet _Wallet; IRateProvider _RateProvider; @@ -58,7 +57,6 @@ namespace BTCPayServer.Controllers Network network, InvoiceRepository invoiceRepository, UserManager userManager, - TokenRepository tokenRepository, BTCPayWallet wallet, IRateProvider rateProvider, StoreRepository storeRepository, @@ -69,7 +67,6 @@ namespace BTCPayServer.Controllers _Explorer = explorerClient ?? throw new ArgumentNullException(nameof(explorerClient)); _StoreRepository = storeRepository ?? throw new ArgumentNullException(nameof(storeRepository)); _Network = network ?? throw new ArgumentNullException(nameof(network)); - _TokenRepository = tokenRepository ?? throw new ArgumentNullException(nameof(tokenRepository)); _InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository)); _Wallet = wallet ?? throw new ArgumentNullException(nameof(wallet)); _RateProvider = rateProvider ?? throw new ArgumentNullException(nameof(rateProvider)); @@ -78,7 +75,7 @@ namespace BTCPayServer.Controllers _FeeProvider = feeProvider ?? throw new ArgumentNullException(nameof(feeProvider)); } - private async Task> CreateInvoiceCore(Invoice invoice, StoreData store) + internal async Task> CreateInvoiceCore(Invoice invoice, StoreData store, string serverUrl) { var derivationStrategy = store.DerivationStrategy; var entity = new InvoiceEntity @@ -91,7 +88,7 @@ namespace BTCPayServer.Controllers notificationUri = null; EmailAddressAttribute emailValidator = new EmailAddressAttribute(); entity.ExpirationTime = entity.InvoiceTime + TimeSpan.FromMinutes(15.0); - entity.ServerUrl = HttpContext.Request.GetAbsoluteRoot(); + entity.ServerUrl = serverUrl; entity.FullNotifications = invoice.FullNotifications; entity.NotificationURL = notificationUri?.AbsoluteUri; entity.BuyerInformation = Map(invoice); diff --git a/BTCPayServer/Hosting/BTCPayServerServices.cs b/BTCPayServer/Hosting/BTCPayServerServices.cs index 11a10070d..863fe3753 100644 --- a/BTCPayServer/Hosting/BTCPayServerServices.cs +++ b/BTCPayServer/Hosting/BTCPayServerServices.cs @@ -141,6 +141,7 @@ namespace BTCPayServer.Hosting services.TryAddSingleton(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); // Add application services. services.AddTransient(); diff --git a/BTCPayServer/Hosting/Startup.cs b/BTCPayServer/Hosting/Startup.cs index fdef043f9..47b7b8f85 100644 --- a/BTCPayServer/Hosting/Startup.cs +++ b/BTCPayServer/Hosting/Startup.cs @@ -35,6 +35,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using System.Threading; using Microsoft.Extensions.Options; using Microsoft.ApplicationInsights.AspNetCore.Extensions; +using Microsoft.AspNetCore.Mvc.Cors.Internal; namespace BTCPayServer.Hosting { @@ -106,7 +107,13 @@ namespace BTCPayServer.Hosting })); services.AddHangfire(configuration); - services.AddCors(); + services.AddCors(o => + { + o.AddPolicy("BitpayAPI", b => + { + b.AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); + }); + }); services.Configure>(o => { @@ -135,10 +142,6 @@ namespace BTCPayServer.Hosting app.UsePayServer(); app.UseStaticFiles(); app.UseAuthentication(); - app.UseCors(b => - { - b.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); - }); app.UseHangfireServer(); app.UseHangfireDashboard("/hangfire", new DashboardOptions() { Authorization = new[] { new NeedRole(Roles.ServerAdmin) } }); app.UseMvc(routes =>