diff --git a/BTCPayServer.Tests/BTCPayServerTester.cs b/BTCPayServer.Tests/BTCPayServerTester.cs index 956defe20..da6ad0016 100644 --- a/BTCPayServer.Tests/BTCPayServerTester.cs +++ b/BTCPayServer.Tests/BTCPayServerTester.cs @@ -122,7 +122,7 @@ namespace BTCPayServer.Tests ServerUri = new Uri("http://" + HostName + ":" + Port + "/"); Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); - var conf = new DefaultConfiguration() { Logger = Logs.LogProvider.CreateLogger("Console") }.CreateConfiguration(new[] { "--datadir", _Directory, "--conf", confPath }); + var conf = new DefaultConfiguration() { Logger = Logs.LogProvider.CreateLogger("Console") }.CreateConfiguration(new[] { "--datadir", _Directory, "--conf", confPath, "--disable-registration", "false" }); _Host = new WebHostBuilder() .UseConfiguration(conf) .ConfigureServices(s => diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index 4667e8ce4..ee4060414 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -101,7 +101,7 @@ namespace BTCPayServer.Tests Rate = 10513.44m, }.SetPaymentMethodDetails(new BTCPayServer.Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod() { - NetworkFee = Money.Coins(0.00000100m), + NextNetworkFee = Money.Coins(0.00000100m), DepositAddress = dummy })); paymentMethods.Add(new PaymentMethod() @@ -110,7 +110,7 @@ namespace BTCPayServer.Tests Rate = 216.79m }.SetPaymentMethodDetails(new BTCPayServer.Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod() { - NetworkFee = Money.Coins(0.00010000m), + NextNetworkFee = Money.Coins(0.00010000m), DepositAddress = dummy })); invoiceEntity.SetPaymentMethods(paymentMethods); @@ -150,7 +150,7 @@ namespace BTCPayServer.Tests var entity = new InvoiceEntity(); #pragma warning disable CS0618 entity.Payments = new System.Collections.Generic.List(); - entity.SetPaymentMethod(new PaymentMethod() { CryptoCode = "BTC", Rate = 5000, NetworkFee = Money.Coins(0.1m) }); + entity.SetPaymentMethod(new PaymentMethod() { CryptoCode = "BTC", Rate = 5000, NextNetworkFee = Money.Coins(0.1m) }); entity.ProductInformation = new ProductInformation() { Price = 5000 }; var paymentMethod = entity.GetPaymentMethods(null).TryGet("BTC", PaymentTypes.BTCLike); @@ -190,13 +190,13 @@ namespace BTCPayServer.Tests { CryptoCode = "BTC", Rate = 1000, - NetworkFee = Money.Coins(0.1m) + NextNetworkFee = Money.Coins(0.1m) }); paymentMethods.Add(new PaymentMethod() { CryptoCode = "LTC", Rate = 500, - NetworkFee = Money.Coins(0.01m) + NextNetworkFee = Money.Coins(0.01m) }); entity.SetPaymentMethods(paymentMethods); entity.Payments = new List(); @@ -275,7 +275,7 @@ namespace BTCPayServer.Tests var entity = new InvoiceEntity(); #pragma warning disable CS0618 entity.Payments = new List(); - entity.SetPaymentMethod(new PaymentMethod() { CryptoCode = "BTC", Rate = 5000, NetworkFee = Money.Coins(0.1m) }); + entity.SetPaymentMethod(new PaymentMethod() { CryptoCode = "BTC", Rate = 5000, NextNetworkFee = Money.Coins(0.1m) }); entity.ProductInformation = new ProductInformation() { Price = 5000 }; entity.PaymentTolerance = 0; diff --git a/BTCPayServer/Configuration/BTCPayServerOptions.cs b/BTCPayServer/Configuration/BTCPayServerOptions.cs index d657f6944..b40470f40 100644 --- a/BTCPayServer/Configuration/BTCPayServerOptions.cs +++ b/BTCPayServer/Configuration/BTCPayServerOptions.cs @@ -61,6 +61,12 @@ namespace BTCPayServer.Configuration set; } = new List(); + public bool DisableRegistration + { + get; + private set; + } + public static string GetDebugLog(IConfiguration configuration) { return configuration.GetValue("debuglog", null); @@ -237,6 +243,8 @@ namespace BTCPayServer.Configuration Logs.Configuration.LogInformation("LogFile: " + LogFile); Logs.Configuration.LogInformation("Log Level: " + GetDebugLogLevel(conf)); } + + DisableRegistration = conf.GetOrDefault("disable-registration", true); } private SSHSettings ParseSSHConfiguration(IConfiguration conf) diff --git a/BTCPayServer/Configuration/DefaultConfiguration.cs b/BTCPayServer/Configuration/DefaultConfiguration.cs index 6717312d7..e89705953 100644 --- a/BTCPayServer/Configuration/DefaultConfiguration.cs +++ b/BTCPayServer/Configuration/DefaultConfiguration.cs @@ -43,6 +43,7 @@ namespace BTCPayServer.Configuration app.Option("--sshtrustedfingerprints", "SSH Host public key fingerprint or sha256 (default: empty, it will allow untrusted connections)", CommandOptionType.SingleValue); app.Option("--debuglog", "A rolling log file for debug messages.", CommandOptionType.SingleValue); app.Option("--debugloglevel", "The severity you log (default:information)", CommandOptionType.SingleValue); + app.Option("--disable-registration", "Disables new user registrations (default:true)", CommandOptionType.SingleValue); foreach (var network in provider.GetAll()) { var crypto = network.CryptoCode.ToLowerInvariant(); diff --git a/BTCPayServer/Controllers/AccountController.cs b/BTCPayServer/Controllers/AccountController.cs index fa486a2a2..39e083e35 100644 --- a/BTCPayServer/Controllers/AccountController.cs +++ b/BTCPayServer/Controllers/AccountController.cs @@ -32,6 +32,7 @@ namespace BTCPayServer.Controllers StoreRepository storeRepository; RoleManager _RoleManager; SettingsRepository _SettingsRepository; + Configuration.BTCPayServerOptions _Options; ILogger _logger; public AccountController( @@ -40,7 +41,8 @@ namespace BTCPayServer.Controllers StoreRepository storeRepository, SignInManager signInManager, IEmailSender emailSender, - SettingsRepository settingsRepository) + SettingsRepository settingsRepository, + Configuration.BTCPayServerOptions options) { this.storeRepository = storeRepository; _userManager = userManager; @@ -48,6 +50,7 @@ namespace BTCPayServer.Controllers _emailSender = emailSender; _RoleManager = roleManager; _SettingsRepository = settingsRepository; + _Options = options; _logger = Logs.PayServer; } @@ -271,6 +274,13 @@ namespace BTCPayServer.Controllers { await _RoleManager.CreateAsync(new IdentityRole(Roles.ServerAdmin)); await _userManager.AddToRoleAsync(user, Roles.ServerAdmin); + + if(_Options.DisableRegistration) + { + // Once the admin user has been created lock subsequent user registrations (needs to be disabled for unit tests that require multiple users). + policies.LockSubscription = true; + await _SettingsRepository.UpdateSetting(policies); + } } var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); diff --git a/BTCPayServer/Controllers/InvoiceController.UI.cs b/BTCPayServer/Controllers/InvoiceController.UI.cs index 1e27b9ab4..a0238c6e0 100644 --- a/BTCPayServer/Controllers/InvoiceController.UI.cs +++ b/BTCPayServer/Controllers/InvoiceController.UI.cs @@ -304,7 +304,7 @@ namespace BTCPayServer.Controllers #pragma warning disable CS0618 // Type or member is obsolete Status = invoice.StatusString, #pragma warning restore CS0618 // Type or member is obsolete - NetworkFee = paymentMethodDetails.GetNetworkFee(), + NetworkFee = paymentMethodDetails.GetNextNetworkFee(), IsMultiCurrency = invoice.GetPayments().Select(p => p.GetPaymentMethodId()).Concat(new[] { paymentMethod.GetId() }).Distinct().Count() > 1, ChangellyEnabled = changelly != null, ChangellyMerchantId = changelly?.ChangellyMerchantId, diff --git a/BTCPayServer/Controllers/InvoiceController.cs b/BTCPayServer/Controllers/InvoiceController.cs index 47c46a615..eda115aa2 100644 --- a/BTCPayServer/Controllers/InvoiceController.cs +++ b/BTCPayServer/Controllers/InvoiceController.cs @@ -240,7 +240,7 @@ namespace BTCPayServer.Controllers #pragma warning disable CS0618 if (paymentMethod.GetId().IsBTCOnChain) { - entity.TxFee = paymentMethod.NetworkFee; + entity.TxFee = paymentMethod.NextNetworkFee; entity.Rate = paymentMethod.Rate; entity.DepositAddress = paymentMethod.DepositAddress; } diff --git a/BTCPayServer/Payments/Bitcoin/BitcoinLikeOnChainPaymentMethod.cs b/BTCPayServer/Payments/Bitcoin/BitcoinLikeOnChainPaymentMethod.cs index 4cc0d91af..30e25801c 100644 --- a/BTCPayServer/Payments/Bitcoin/BitcoinLikeOnChainPaymentMethod.cs +++ b/BTCPayServer/Payments/Bitcoin/BitcoinLikeOnChainPaymentMethod.cs @@ -20,9 +20,9 @@ namespace BTCPayServer.Payments.Bitcoin return DepositAddress; } - public decimal GetNetworkFee() + public decimal GetNextNetworkFee() { - return NetworkFee.ToDecimal(MoneyUnit.BTC); + return NextNetworkFee.ToDecimal(MoneyUnit.BTC); } public void SetPaymentDestination(string newPaymentDestination) { @@ -34,7 +34,7 @@ namespace BTCPayServer.Payments.Bitcoin [JsonIgnore] public FeeRate FeeRate { get; set; } [JsonIgnore] - public Money NetworkFee { get; set; } + public Money NextNetworkFee { get; set; } [JsonIgnore] public String DepositAddress { get; set; } public BitcoinAddress GetDepositAddress(Network network) diff --git a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs index 758fdc5fa..e7a830b86 100644 --- a/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs +++ b/BTCPayServer/Payments/Bitcoin/BitcoinLikePaymentHandler.cs @@ -53,11 +53,11 @@ namespace BTCPayServer.Payments.Bitcoin switch (onchainMethod.NetworkFeeMode) { case NetworkFeeMode.Always: - onchainMethod.NetworkFee = onchainMethod.FeeRate.GetFee(100); // assume price for 100 bytes + onchainMethod.NextNetworkFee = onchainMethod.FeeRate.GetFee(100); // assume price for 100 bytes break; case NetworkFeeMode.Never: case NetworkFeeMode.MultiplePaymentsOnly: - onchainMethod.NetworkFee = Money.Zero; + onchainMethod.NextNetworkFee = Money.Zero; break; } onchainMethod.DepositAddress = (await prepare.ReserveAddress).ToString(); diff --git a/BTCPayServer/Payments/IPaymentMethodDetails.cs b/BTCPayServer/Payments/IPaymentMethodDetails.cs index b6d472b1e..eab9c8853 100644 --- a/BTCPayServer/Payments/IPaymentMethodDetails.cs +++ b/BTCPayServer/Payments/IPaymentMethodDetails.cs @@ -18,10 +18,10 @@ namespace BTCPayServer.Payments string GetPaymentDestination(); PaymentTypes GetPaymentType(); /// - /// Returns what a merchant would need to pay to cashout this payment + /// Returns fee that the merchant charge to the customer for the next payment /// /// - decimal GetNetworkFee(); + decimal GetNextNetworkFee(); /// /// Change the payment destination (internal plumbing) /// diff --git a/BTCPayServer/Payments/Lightning/LightningLikePaymentMethodDetails.cs b/BTCPayServer/Payments/Lightning/LightningLikePaymentMethodDetails.cs index a396e5ca3..c8edcba93 100644 --- a/BTCPayServer/Payments/Lightning/LightningLikePaymentMethodDetails.cs +++ b/BTCPayServer/Payments/Lightning/LightningLikePaymentMethodDetails.cs @@ -22,7 +22,7 @@ namespace BTCPayServer.Payments.Lightning return PaymentTypes.LightningLike; } - public decimal GetNetworkFee() + public decimal GetNextNetworkFee() { return 0.0m; } diff --git a/BTCPayServer/Services/Invoices/InvoiceEntity.cs b/BTCPayServer/Services/Invoices/InvoiceEntity.cs index 54050bbc0..0bc8fa914 100644 --- a/BTCPayServer/Services/Invoices/InvoiceEntity.cs +++ b/BTCPayServer/Services/Invoices/InvoiceEntity.cs @@ -730,7 +730,7 @@ namespace BTCPayServer.Services.Invoices { FeeRate = FeeRate, DepositAddress = string.IsNullOrEmpty(DepositAddress) ? null : DepositAddress, - NetworkFee = NetworkFee + NextNetworkFee = NextNetworkFee }; } else @@ -738,7 +738,7 @@ namespace BTCPayServer.Services.Invoices var details = PaymentMethodExtensions.DeserializePaymentMethodDetails(GetId(), PaymentMethodDetails); if (details is Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod btcLike) { - btcLike.NetworkFee = NetworkFee; + btcLike.NextNetworkFee = NextNetworkFee; btcLike.DepositAddress = string.IsNullOrEmpty(DepositAddress) ? null : DepositAddress; btcLike.FeeRate = FeeRate; } @@ -760,7 +760,7 @@ namespace BTCPayServer.Services.Invoices if (paymentMethod is Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod bitcoinPaymentMethod) { - NetworkFee = bitcoinPaymentMethod.NetworkFee; + NextNetworkFee = bitcoinPaymentMethod.NextNetworkFee; FeeRate = bitcoinPaymentMethod.FeeRate; DepositAddress = bitcoinPaymentMethod.DepositAddress; } @@ -775,8 +775,8 @@ namespace BTCPayServer.Services.Invoices [Obsolete("Use ((BitcoinLikeOnChainPaymentMethod)GetPaymentMethod()).FeeRate")] public FeeRate FeeRate { get; set; } [JsonProperty(PropertyName = "txFee")] - [Obsolete("Use ((BitcoinLikeOnChainPaymentMethod)GetPaymentMethod()).TxFee")] - public Money NetworkFee { get; set; } + [Obsolete("Use ((BitcoinLikeOnChainPaymentMethod)GetPaymentMethod()).NextNetworkFee")] + public Money NextNetworkFee { get; set; } [JsonProperty(PropertyName = "depositAddress")] [Obsolete("Use ((BitcoinLikeOnChainPaymentMethod)GetPaymentMethod()).DepositAddress")] public string DepositAddress { get; set; } @@ -841,7 +841,7 @@ namespace BTCPayServer.Services.Invoices var method = GetPaymentMethodDetails(); if (method == null) return 0.0m; - return method.GetNetworkFee(); + return method.GetNextNetworkFee(); } } diff --git a/BTCPayServer/Services/Invoices/InvoiceRepository.cs b/BTCPayServer/Services/Invoices/InvoiceRepository.cs index ba9f5bd19..314a90bfa 100644 --- a/BTCPayServer/Services/Invoices/InvoiceRepository.cs +++ b/BTCPayServer/Services/Invoices/InvoiceRepository.cs @@ -393,7 +393,7 @@ retry: paymentMethods = entity.GetPaymentMethods(null); var paymentMethodDetails = paymentMethods.TryGet(paymentEntity.GetPaymentMethodId())?.GetPaymentMethodDetails(); if (paymentMethodDetails != null) // == null should never happen, but we never know. - paymentEntity.NetworkFee = paymentMethodDetails.GetNetworkFee(); + paymentEntity.NetworkFee = paymentMethodDetails.GetNextNetworkFee(); } return paymentEntity; @@ -582,15 +582,15 @@ retry: #pragma warning restore CS0618 ReceivedTime = date.UtcDateTime, Accounted = accounted, - NetworkFee = paymentMethodDetails.GetNetworkFee() + NetworkFee = paymentMethodDetails.GetNextNetworkFee() }; entity.SetCryptoPaymentData(paymentData); if (paymentMethodDetails is Payments.Bitcoin.BitcoinLikeOnChainPaymentMethod bitcoinPaymentMethod && bitcoinPaymentMethod.NetworkFeeMode == NetworkFeeMode.MultiplePaymentsOnly && - bitcoinPaymentMethod.NetworkFee == Money.Zero) + bitcoinPaymentMethod.NextNetworkFee == Money.Zero) { - bitcoinPaymentMethod.NetworkFee = bitcoinPaymentMethod.FeeRate.GetFee(100); // assume price for 100 bytes + bitcoinPaymentMethod.NextNetworkFee = bitcoinPaymentMethod.FeeRate.GetFee(100); // assume price for 100 bytes paymentMethod.SetPaymentMethodDetails(bitcoinPaymentMethod); invoiceEntity.SetPaymentMethod(paymentMethod); invoice.Blob = ToBytes(invoiceEntity, network.NBitcoinNetwork);