mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-20 13:34:37 +01:00
Allow resolution of any settings via DI
This commit is contained in:
parent
3285f24fe9
commit
67eeb4b69a
41 changed files with 221 additions and 149 deletions
|
@ -72,14 +72,14 @@ namespace BTCPayServer.Tests
|
|||
|
||||
// Setup Lightning
|
||||
var controller = user.GetController<UIStoresController>();
|
||||
var lightningVm = (LightningNodeViewModel)Assert.IsType<ViewResult>(await controller.SetupLightningNode(user.StoreId, cryptoCode)).Model;
|
||||
var lightningVm = (LightningNodeViewModel)Assert.IsType<ViewResult>(controller.SetupLightningNode(user.StoreId, cryptoCode)).Model;
|
||||
Assert.True(lightningVm.Enabled);
|
||||
var response = await controller.SetLightningNodeEnabled(user.StoreId, cryptoCode, false);
|
||||
Assert.IsType<RedirectToActionResult>(response);
|
||||
|
||||
// Get enabled state from settings
|
||||
LightningSettingsViewModel lnSettingsModel;
|
||||
response = controller.LightningSettings(user.StoreId, cryptoCode).GetAwaiter().GetResult();
|
||||
response = controller.LightningSettings(user.StoreId, cryptoCode);
|
||||
lnSettingsModel = (LightningSettingsViewModel)Assert.IsType<ViewResult>(response).Model;
|
||||
Assert.NotNull(lnSettingsModel?.ConnectionString);
|
||||
Assert.False(lnSettingsModel.Enabled);
|
||||
|
|
|
@ -137,8 +137,6 @@ namespace BTCPayServer.Tests
|
|||
}
|
||||
if (CheatMode)
|
||||
config.AppendLine("cheatmode=1");
|
||||
if (Experimental)
|
||||
config.AppendLine("experimental=1");
|
||||
|
||||
config.AppendLine($"torrcfile={TestUtils.GetTestDataFullPath("Tor/torrc")}");
|
||||
config.AppendLine($"socksendpoint={SocksEndpoint}");
|
||||
|
@ -293,7 +291,6 @@ namespace BTCPayServer.Tests
|
|||
public string SSHKeyFile { get; internal set; }
|
||||
public string SSHConnection { get; set; }
|
||||
public bool NoCSP { get; set; }
|
||||
public bool Experimental { get; internal set; }
|
||||
|
||||
public T GetController<T>(string userId = null, string storeId = null, bool isAdmin = false) where T : Controller
|
||||
{
|
||||
|
@ -342,5 +339,13 @@ namespace BTCPayServer.Tests
|
|||
var index = coinAverageMock.ExchangeRates.FindIndex(o => o.CurrencyPair == p);
|
||||
coinAverageMock.ExchangeRates[index] = new PairRate(p, bidAsk);
|
||||
}
|
||||
|
||||
public async Task EnableExperimental()
|
||||
{
|
||||
var r = GetService<SettingsRepository>();
|
||||
var p = await r.GetSettingAsync<PoliciesSettings>() ?? new PoliciesSettings();
|
||||
p.Experimental = true;
|
||||
await r.UpdateSetting(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2519,8 +2519,8 @@ namespace BTCPayServer.Tests
|
|||
public async Task CustodiansControllerTests()
|
||||
{
|
||||
using var tester = CreateServerTester();
|
||||
tester.PayTester.Experimental = true;
|
||||
await tester.StartAsync();
|
||||
await tester.PayTester.EnableExperimental();
|
||||
var unauthClient = new BTCPayServerClient(tester.PayTester.ServerUri);
|
||||
await AssertHttpError(401, async () => await unauthClient.GetCustodians());
|
||||
|
||||
|
@ -2539,8 +2539,8 @@ namespace BTCPayServer.Tests
|
|||
{
|
||||
|
||||
using var tester = CreateServerTester();
|
||||
tester.PayTester.Experimental = true;
|
||||
await tester.StartAsync();
|
||||
await tester.PayTester.EnableExperimental();
|
||||
|
||||
var admin = tester.NewAccount();
|
||||
await admin.GrantAccessAsync(true);
|
||||
|
@ -2711,9 +2711,9 @@ namespace BTCPayServer.Tests
|
|||
public async Task CustodianTests()
|
||||
{
|
||||
using var tester = CreateServerTester();
|
||||
tester.PayTester.Experimental = true;
|
||||
await tester.StartAsync();
|
||||
|
||||
await tester.PayTester.EnableExperimental();
|
||||
|
||||
var admin = tester.NewAccount();
|
||||
await admin.GrantAccessAsync(true);
|
||||
|
||||
|
|
|
@ -408,7 +408,7 @@ namespace BTCPayServer.Tests
|
|||
var storeController = user.GetController<UIStoresController>();
|
||||
var storeResponse = storeController.GeneralSettings();
|
||||
Assert.IsType<ViewResult>(storeResponse);
|
||||
Assert.IsType<ViewResult>(await storeController.SetupLightningNode(user.StoreId, "BTC"));
|
||||
Assert.IsType<ViewResult>(storeController.SetupLightningNode(user.StoreId, "BTC"));
|
||||
|
||||
storeController.SetupLightningNode(user.StoreId, new LightningNodeViewModel
|
||||
{
|
||||
|
@ -430,7 +430,7 @@ namespace BTCPayServer.Tests
|
|||
new LightningNodeViewModel { ConnectionString = tester.MerchantCharge.Client.Uri.AbsoluteUri },
|
||||
"save", "BTC").GetAwaiter().GetResult());
|
||||
|
||||
storeResponse = storeController.LightningSettings(user.StoreId, "BTC").GetAwaiter().GetResult();
|
||||
storeResponse = storeController.LightningSettings(user.StoreId, "BTC");
|
||||
var storeVm =
|
||||
Assert.IsType<LightningSettingsViewModel>(Assert
|
||||
.IsType<ViewResult>(storeResponse).Model);
|
||||
|
@ -1571,7 +1571,7 @@ namespace BTCPayServer.Tests
|
|||
|
||||
// enable unified QR code in settings
|
||||
var vm = Assert.IsType<LightningSettingsViewModel>(Assert
|
||||
.IsType<ViewResult>(await user.GetController<UIStoresController>().LightningSettings(user.StoreId, cryptoCode)).Model
|
||||
.IsType<ViewResult>(user.GetController<UIStoresController>().LightningSettings(user.StoreId, cryptoCode)).Model
|
||||
);
|
||||
vm.OnChainWithLnInvoiceFallback = true;
|
||||
Assert.IsType<RedirectToActionResult>(
|
||||
|
@ -1629,7 +1629,7 @@ namespace BTCPayServer.Tests
|
|||
|
||||
// Activating LNUrl, we should still have only 1 payment criteria that can be set.
|
||||
user.RegisterLightningNode(cryptoCode, LightningConnectionType.Charge);
|
||||
var lnSettingsVm = await user.GetController<UIStoresController>().LightningSettings(user.StoreId, cryptoCode).AssertViewModelAsync<LightningSettingsViewModel>();
|
||||
var lnSettingsVm = user.GetController<UIStoresController>().LightningSettings(user.StoreId, cryptoCode).AssertViewModel<LightningSettingsViewModel>();
|
||||
lnSettingsVm.LNURLEnabled = true;
|
||||
lnSettingsVm.LNURLStandardInvoiceEnabled = true;
|
||||
Assert.IsType<RedirectToActionResult>(user.GetController<UIStoresController>().LightningSettings(lnSettingsVm).Result);
|
||||
|
|
|
@ -8,16 +8,15 @@
|
|||
@using BTCPayServer.Abstractions.Extensions
|
||||
@using BTCPayServer.Abstractions.Contracts
|
||||
@using BTCPayServer.Client
|
||||
@using BTCPayServer.Services
|
||||
@inject BTCPayServer.Services.BTCPayServerEnvironment Env
|
||||
@inject SignInManager<ApplicationUser> SignInManager
|
||||
@inject ISettingsRepository SettingsRepository
|
||||
@inject PoliciesSettings PoliciesSettings
|
||||
@inject ThemeSettings Theme
|
||||
|
||||
@model BTCPayServer.Components.MainNav.MainNavViewModel
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
|
||||
@{
|
||||
var theme = await SettingsRepository.GetTheme();
|
||||
}
|
||||
|
||||
<nav id="mainNav" class="d-flex flex-column justify-content-between">
|
||||
<div class="accordion px-3 px-lg-4">
|
||||
|
@ -222,7 +221,7 @@
|
|||
else if (Env.IsSecure)
|
||||
{
|
||||
<ul class="navbar-nav">
|
||||
@if (!(await SettingsRepository.GetPolicies()).LockSubscription)
|
||||
@if (!PoliciesSettings.LockSubscription)
|
||||
{
|
||||
<li class="nav-item">
|
||||
<a asp-area="" asp-controller="UIAccount" asp-action="Register" class="nav-link js-scroll-trigger" id="Nav-Register">Register</a>
|
||||
|
@ -256,7 +255,7 @@
|
|||
<div class="text-secondary">Administrator</div>
|
||||
}
|
||||
</li>
|
||||
@if (!theme.CustomTheme)
|
||||
@if (!Theme.CustomTheme)
|
||||
{
|
||||
<li class="border-top py-1 px-3">
|
||||
<vc:theme-switch css-class="nav-link"/>
|
||||
|
|
|
@ -147,7 +147,6 @@ namespace BTCPayServer.Configuration
|
|||
PluginRemote = conf.GetOrDefault("plugin-remote", "btcpayserver/btcpayserver-plugins");
|
||||
RecommendedPlugins = conf.GetOrDefault("recommended-plugins", "").ToLowerInvariant().Split('\r', '\n', '\t', ' ').Where(s => !string.IsNullOrEmpty(s)).Distinct().ToArray();
|
||||
CheatMode = conf.GetOrDefault("cheatmode", false);
|
||||
Experimental = conf.GetOrDefault("experimental", false);
|
||||
if (CheatMode && this.NetworkType == ChainName.Mainnet)
|
||||
throw new ConfigException($"cheatmode can't be used on mainnet");
|
||||
}
|
||||
|
@ -155,7 +154,6 @@ namespace BTCPayServer.Configuration
|
|||
public string PluginRemote { get; set; }
|
||||
public string[] RecommendedPlugins { get; set; }
|
||||
public bool CheatMode { get; set; }
|
||||
public bool Experimental { get; set; }
|
||||
|
||||
private SSHSettings ParseSSHConfiguration(IConfiguration conf)
|
||||
{
|
||||
|
|
|
@ -50,7 +50,6 @@ namespace BTCPayServer.Configuration
|
|||
app.Option("--recommended-plugins", "Plugins which would be marked as recommended to be installed. Separated by newline or space", CommandOptionType.MultipleValue);
|
||||
app.Option("--xforwardedproto", "If specified, set X-Forwarded-Proto to the specified value, this may be useful if your reverse proxy handle https but is not configured to add X-Forwarded-Proto (example: --xforwardedproto https)", CommandOptionType.SingleValue);
|
||||
app.Option("--cheatmode", "Add some helper UI to facilitate dev-time testing (Default false)", CommandOptionType.BoolValue);
|
||||
app.Option("--experimental", "Enable experimental features (Default false)", CommandOptionType.BoolValue);
|
||||
|
||||
app.Option("--explorerpostgres", $"Connection string to the postgres database of NBXplorer. (optional, used for dashboard and reporting features)", CommandOptionType.SingleValue);
|
||||
foreach (var network in provider.GetAll().OfType<BTCPayNetwork>())
|
||||
|
|
|
@ -28,10 +28,10 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
|
||||
|
||||
public GreenfieldInternalLightningNodeApiController(
|
||||
BTCPayNetworkProvider btcPayNetworkProvider, ISettingsRepository settingsRepository, LightningClientFactoryService lightningClientFactory,
|
||||
BTCPayNetworkProvider btcPayNetworkProvider, PoliciesSettings policiesSettings, LightningClientFactoryService lightningClientFactory,
|
||||
IOptions<LightningNetworkOptions> lightningNetworkOptions,
|
||||
IAuthorizationService authorizationService) : base(
|
||||
btcPayNetworkProvider, settingsRepository, authorizationService)
|
||||
btcPayNetworkProvider, policiesSettings, authorizationService)
|
||||
{
|
||||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||
_lightningClientFactory = lightningClientFactory;
|
||||
|
|
|
@ -32,9 +32,9 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
public GreenfieldStoreLightningNodeApiController(
|
||||
IOptions<LightningNetworkOptions> lightningNetworkOptions,
|
||||
LightningClientFactoryService lightningClientFactory, BTCPayNetworkProvider btcPayNetworkProvider,
|
||||
ISettingsRepository settingsRepository,
|
||||
PoliciesSettings policiesSettings,
|
||||
IAuthorizationService authorizationService) : base(
|
||||
btcPayNetworkProvider, settingsRepository, authorizationService)
|
||||
btcPayNetworkProvider, policiesSettings, authorizationService)
|
||||
{
|
||||
_lightningNetworkOptions = lightningNetworkOptions;
|
||||
_lightningClientFactory = lightningClientFactory;
|
||||
|
|
|
@ -8,6 +8,7 @@ using BTCPayServer.Client;
|
|||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Lightning;
|
||||
using BTCPayServer.Security;
|
||||
using BTCPayServer.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
@ -26,14 +27,14 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
public abstract class GreenfieldLightningNodeApiController : Controller
|
||||
{
|
||||
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
|
||||
private readonly ISettingsRepository _settingsRepository;
|
||||
private readonly PoliciesSettings _policiesSettings;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
protected GreenfieldLightningNodeApiController(BTCPayNetworkProvider btcPayNetworkProvider,
|
||||
ISettingsRepository settingsRepository,
|
||||
PoliciesSettings policiesSettings,
|
||||
IAuthorizationService authorizationService)
|
||||
{
|
||||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||
_settingsRepository = settingsRepository;
|
||||
_policiesSettings = policiesSettings;
|
||||
_authorizationService = authorizationService;
|
||||
}
|
||||
|
||||
|
@ -296,8 +297,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
|
||||
protected async Task<bool> CanUseInternalLightning(bool doingAdminThings)
|
||||
{
|
||||
|
||||
return (!doingAdminThings && (await _settingsRepository.GetPolicies()).AllowLightningInternalNodeForAll) ||
|
||||
return (!doingAdminThings && this._policiesSettings.AllowLightningInternalNodeForAll) ||
|
||||
(await _authorizationService.AuthorizeAsync(User, null,
|
||||
new PolicyRequirement(Policies.CanUseInternalLightningNode))).Succeeded;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ using BTCPayServer.Lightning;
|
|||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Payments.Lightning;
|
||||
using BTCPayServer.Security;
|
||||
using BTCPayServer.Services;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
@ -28,6 +29,9 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
public class GreenfieldStoreLightningNetworkPaymentMethodsController : ControllerBase
|
||||
{
|
||||
private StoreData Store => HttpContext.GetStoreData();
|
||||
|
||||
public PoliciesSettings PoliciesSettings { get; }
|
||||
|
||||
private readonly StoreRepository _storeRepository;
|
||||
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
@ -37,12 +41,14 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
StoreRepository storeRepository,
|
||||
BTCPayNetworkProvider btcPayNetworkProvider,
|
||||
IAuthorizationService authorizationService,
|
||||
ISettingsRepository settingsRepository)
|
||||
ISettingsRepository settingsRepository,
|
||||
PoliciesSettings policiesSettings)
|
||||
{
|
||||
_storeRepository = storeRepository;
|
||||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||
_authorizationService = authorizationService;
|
||||
_settingsRepository = settingsRepository;
|
||||
PoliciesSettings = policiesSettings;
|
||||
}
|
||||
|
||||
public static IEnumerable<LightningNetworkPaymentMethodData> GetLightningPaymentMethods(StoreData store,
|
||||
|
@ -216,7 +222,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
|
||||
private async Task<bool> CanUseInternalLightning()
|
||||
{
|
||||
return (await _settingsRepository.GetPolicies()).AllowLightningInternalNodeForAll ||
|
||||
return PoliciesSettings.AllowLightningInternalNodeForAll ||
|
||||
(await _authorizationService.AuthorizeAsync(User, null,
|
||||
new PolicyRequirement(Policies.CanUseInternalLightningNode))).Succeeded;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
|
||||
private async Task<(bool HotWallet, bool RPCImport)> CanUseHotWallet()
|
||||
{
|
||||
return await _authorizationService.CanUseHotWallet(await _settingsRepository.GetPolicies(), User);
|
||||
return await _authorizationService.CanUseHotWallet(PoliciesSettings, User);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ using BTCPayServer.Client.Models;
|
|||
using BTCPayServer.Data;
|
||||
using BTCPayServer.HostedServices;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Services;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using BTCPayServer.Services.Wallets;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
@ -25,11 +26,13 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
public partial class GreenfieldStoreOnChainPaymentMethodsController : ControllerBase
|
||||
{
|
||||
private StoreData Store => HttpContext.GetStoreData();
|
||||
|
||||
public PoliciesSettings PoliciesSettings { get; }
|
||||
|
||||
private readonly StoreRepository _storeRepository;
|
||||
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
|
||||
private readonly BTCPayWalletProvider _walletProvider;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly ISettingsRepository _settingsRepository;
|
||||
private readonly ExplorerClientProvider _explorerClientProvider;
|
||||
|
||||
public GreenfieldStoreOnChainPaymentMethodsController(
|
||||
|
@ -37,14 +40,15 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
BTCPayNetworkProvider btcPayNetworkProvider,
|
||||
BTCPayWalletProvider walletProvider,
|
||||
IAuthorizationService authorizationService,
|
||||
ExplorerClientProvider explorerClientProvider, ISettingsRepository settingsRepository)
|
||||
ExplorerClientProvider explorerClientProvider,
|
||||
PoliciesSettings policiesSettings)
|
||||
{
|
||||
_storeRepository = storeRepository;
|
||||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||
_walletProvider = walletProvider;
|
||||
_authorizationService = authorizationService;
|
||||
_explorerClientProvider = explorerClientProvider;
|
||||
_settingsRepository = settingsRepository;
|
||||
PoliciesSettings = policiesSettings;
|
||||
}
|
||||
|
||||
public static IEnumerable<OnChainPaymentMethodData> GetOnChainPaymentMethods(StoreData store,
|
||||
|
|
|
@ -38,12 +38,14 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
public class GreenfieldStoreOnChainWalletsController : Controller
|
||||
{
|
||||
private StoreData Store => HttpContext.GetStoreData();
|
||||
|
||||
public PoliciesSettings PoliciesSettings { get; }
|
||||
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly BTCPayWalletProvider _btcPayWalletProvider;
|
||||
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
|
||||
private readonly WalletRepository _walletRepository;
|
||||
private readonly ExplorerClientProvider _explorerClientProvider;
|
||||
private readonly ISettingsRepository _settingsRepository;
|
||||
private readonly NBXplorerDashboard _nbXplorerDashboard;
|
||||
private readonly UIWalletsController _walletsController;
|
||||
private readonly PayjoinClient _payjoinClient;
|
||||
|
@ -59,8 +61,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
BTCPayNetworkProvider btcPayNetworkProvider,
|
||||
WalletRepository walletRepository,
|
||||
ExplorerClientProvider explorerClientProvider,
|
||||
ISettingsRepository settingsRepository,
|
||||
NBXplorerDashboard nbXplorerDashboard,
|
||||
PoliciesSettings policiesSettings,
|
||||
UIWalletsController walletsController,
|
||||
PayjoinClient payjoinClient,
|
||||
DelayedTransactionBroadcaster delayedTransactionBroadcaster,
|
||||
|
@ -75,7 +77,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
_btcPayNetworkProvider = btcPayNetworkProvider;
|
||||
_walletRepository = walletRepository;
|
||||
_explorerClientProvider = explorerClientProvider;
|
||||
_settingsRepository = settingsRepository;
|
||||
PoliciesSettings = policiesSettings;
|
||||
_nbXplorerDashboard = nbXplorerDashboard;
|
||||
_walletsController = walletsController;
|
||||
_payjoinClient = payjoinClient;
|
||||
|
@ -615,7 +617,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
|
||||
private async Task<(bool HotWallet, bool RPCImport)> CanUseHotWallet()
|
||||
{
|
||||
return await _authorizationService.CanUseHotWallet(await _settingsRepository.GetPolicies(), User);
|
||||
return await _authorizationService.CanUseHotWallet(PoliciesSettings, User);
|
||||
}
|
||||
|
||||
private bool IsInvalidWalletRequest(string cryptoCode, [MaybeNullWhen(true)] out BTCPayNetwork network,
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
[EnableCors(CorsPolicies.All)]
|
||||
public class GreenfieldUsersController : ControllerBase
|
||||
{
|
||||
public PoliciesSettings PoliciesSettings { get; }
|
||||
public Logs Logs { get; }
|
||||
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
|
@ -42,6 +43,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
public GreenfieldUsersController(UserManager<ApplicationUser> userManager,
|
||||
RoleManager<IdentityRole> roleManager,
|
||||
SettingsRepository settingsRepository,
|
||||
PoliciesSettings policiesSettings,
|
||||
EventAggregator eventAggregator,
|
||||
IPasswordValidator<ApplicationUser> passwordValidator,
|
||||
RateLimitService throttleService,
|
||||
|
@ -54,6 +56,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
_userManager = userManager;
|
||||
_roleManager = roleManager;
|
||||
_settingsRepository = settingsRepository;
|
||||
PoliciesSettings = policiesSettings;
|
||||
_eventAggregator = eventAggregator;
|
||||
_passwordValidator = passwordValidator;
|
||||
_throttleService = throttleService;
|
||||
|
@ -147,7 +150,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
if (request.IsAdministrator is true && !isAdmin)
|
||||
return this.CreateAPIPermissionError(Policies.Unrestricted, $"Insufficient API Permissions. Please use an API key with permission: {Policies.Unrestricted} and be an admin.");
|
||||
|
||||
if (!isAdmin && (policies.LockSubscription || (await _settingsRepository.GetPolicies()).DisableNonAdminCreateUserApi))
|
||||
if (!isAdmin && (policies.LockSubscription || PoliciesSettings.DisableNonAdminCreateUserApi))
|
||||
{
|
||||
// If we are not admin and subscriptions are locked, we need to check the Policies.CanCreateUser.Key permission
|
||||
var canCreateUser = (await _authorizationService.AuthorizeAsync(User, null, new PolicyRequirement(Policies.CanCreateUser))).Succeeded;
|
||||
|
|
|
@ -33,9 +33,9 @@ namespace BTCPayServer.Controllers
|
|||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
readonly RoleManager<IdentityRole> _RoleManager;
|
||||
readonly SettingsRepository _SettingsRepository;
|
||||
readonly Configuration.BTCPayServerOptions _Options;
|
||||
private readonly BTCPayServerEnvironment _btcPayServerEnvironment;
|
||||
readonly SettingsRepository _SettingsRepository;
|
||||
private readonly Fido2Service _fido2Service;
|
||||
private readonly LnurlAuthService _lnurlAuthService;
|
||||
private readonly LinkGenerator _linkGenerator;
|
||||
|
@ -43,12 +43,14 @@ namespace BTCPayServer.Controllers
|
|||
private readonly EventAggregator _eventAggregator;
|
||||
readonly ILogger _logger;
|
||||
|
||||
public PoliciesSettings PoliciesSettings { get; }
|
||||
public Logs Logs { get; }
|
||||
|
||||
public UIAccountController(
|
||||
UserManager<ApplicationUser> userManager,
|
||||
RoleManager<IdentityRole> roleManager,
|
||||
SignInManager<ApplicationUser> signInManager,
|
||||
PoliciesSettings policiesSettings,
|
||||
SettingsRepository settingsRepository,
|
||||
Configuration.BTCPayServerOptions options,
|
||||
BTCPayServerEnvironment btcPayServerEnvironment,
|
||||
|
@ -61,8 +63,9 @@ namespace BTCPayServer.Controllers
|
|||
{
|
||||
_userManager = userManager;
|
||||
_signInManager = signInManager;
|
||||
_RoleManager = roleManager;
|
||||
PoliciesSettings = policiesSettings;
|
||||
_SettingsRepository = settingsRepository;
|
||||
_RoleManager = roleManager;
|
||||
_Options = options;
|
||||
_btcPayServerEnvironment = btcPayServerEnvironment;
|
||||
_fido2Service = fido2Service;
|
||||
|
@ -85,7 +88,7 @@ namespace BTCPayServer.Controllers
|
|||
public async Task<IActionResult> Login(string returnUrl = null, string email = null)
|
||||
{
|
||||
if (User.Identity.IsAuthenticated && string.IsNullOrEmpty(returnUrl))
|
||||
return await RedirectToLocal();
|
||||
return RedirectToLocal();
|
||||
// Clear the existing external cookie to ensure a clean login process
|
||||
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
|
||||
|
||||
|
@ -119,7 +122,7 @@ namespace BTCPayServer.Controllers
|
|||
|
||||
_logger.LogInformation("User with ID {UserId} logged in with a login code.", user.Id);
|
||||
await _signInManager.SignInAsync(user, false, "LoginCode");
|
||||
return await RedirectToLocal(returnUrl);
|
||||
return RedirectToLocal(returnUrl);
|
||||
}
|
||||
return await Login(returnUrl, null);
|
||||
}
|
||||
|
@ -194,7 +197,7 @@ namespace BTCPayServer.Controllers
|
|||
if (result.Succeeded)
|
||||
{
|
||||
_logger.LogInformation($"User '{user.Id}' logged in.");
|
||||
return await RedirectToLocal(returnUrl);
|
||||
return RedirectToLocal(returnUrl);
|
||||
}
|
||||
if (result.RequiresTwoFactor)
|
||||
{
|
||||
|
@ -293,7 +296,7 @@ namespace BTCPayServer.Controllers
|
|||
_lnurlAuthService.FinalLoginStore.TryRemove(viewModel.UserId, out _);
|
||||
await _signInManager.SignInAsync(user, viewModel.RememberMe, "FIDO2");
|
||||
_logger.LogInformation("User logged in.");
|
||||
return await RedirectToLocal(returnUrl);
|
||||
return RedirectToLocal(returnUrl);
|
||||
}
|
||||
|
||||
errorMessage = "Invalid login attempt.";
|
||||
|
@ -344,7 +347,7 @@ namespace BTCPayServer.Controllers
|
|||
{
|
||||
await _signInManager.SignInAsync(user, viewModel.RememberMe, "FIDO2");
|
||||
_logger.LogInformation("User logged in.");
|
||||
return await RedirectToLocal(returnUrl);
|
||||
return RedirectToLocal(returnUrl);
|
||||
}
|
||||
|
||||
errorMessage = "Invalid login attempt.";
|
||||
|
@ -423,7 +426,7 @@ namespace BTCPayServer.Controllers
|
|||
if (result.Succeeded)
|
||||
{
|
||||
_logger.LogInformation("User with ID {UserId} logged in with 2fa.", user.Id);
|
||||
return await RedirectToLocal(returnUrl);
|
||||
return RedirectToLocal(returnUrl);
|
||||
}
|
||||
else if (result.IsLockedOut)
|
||||
{
|
||||
|
@ -492,7 +495,7 @@ namespace BTCPayServer.Controllers
|
|||
if (result.Succeeded)
|
||||
{
|
||||
_logger.LogInformation("User with ID {UserId} logged in with a recovery code.", user.Id);
|
||||
return await RedirectToLocal(returnUrl);
|
||||
return RedirectToLocal(returnUrl);
|
||||
}
|
||||
if (result.IsLockedOut)
|
||||
{
|
||||
|
@ -518,14 +521,13 @@ namespace BTCPayServer.Controllers
|
|||
[HttpGet("/register")]
|
||||
[AllowAnonymous]
|
||||
[RateLimitsFilter(ZoneLimits.Register, Scope = RateLimitsScope.RemoteAddress)]
|
||||
public async Task<IActionResult> Register(string returnUrl = null, bool logon = true)
|
||||
public IActionResult Register(string returnUrl = null, bool logon = true)
|
||||
{
|
||||
if (!CanLoginOrRegister())
|
||||
{
|
||||
SetInsecureFlags();
|
||||
}
|
||||
var policies = await _SettingsRepository.GetSettingAsync<PoliciesSettings>() ?? new PoliciesSettings();
|
||||
if (policies.LockSubscription && !User.IsInRole(Roles.ServerAdmin))
|
||||
if (PoliciesSettings.LockSubscription && !User.IsInRole(Roles.ServerAdmin))
|
||||
return RedirectToAction(nameof(UIHomeController.Index), "UIHome");
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
return View();
|
||||
|
@ -583,7 +585,7 @@ namespace BTCPayServer.Controllers
|
|||
{
|
||||
if (logon)
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
return await RedirectToLocal(returnUrl);
|
||||
return RedirectToLocal(returnUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -750,7 +752,7 @@ namespace BTCPayServer.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<IActionResult> RedirectToLocal(string returnUrl = null)
|
||||
private IActionResult RedirectToLocal(string returnUrl = null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
|
||||
{
|
||||
|
@ -759,10 +761,9 @@ namespace BTCPayServer.Controllers
|
|||
else
|
||||
{
|
||||
// After login, if there is an app on "/", we should redirect to BTCPay explicit home route, and not to the app.
|
||||
var policies = await _SettingsRepository.GetPolicies();
|
||||
if (policies?.RootAppId is not null && policies?.RootAppType is not null)
|
||||
if (PoliciesSettings.RootAppId is not null && PoliciesSettings.RootAppType is not null)
|
||||
return RedirectToAction(nameof(UIHomeController.Home), "UIHome");
|
||||
if (policies?.DomainToAppMapping is { } mapping)
|
||||
if (PoliciesSettings.DomainToAppMapping is { } mapping)
|
||||
{
|
||||
var matchedDomainMapping = mapping.FirstOrDefault(item =>
|
||||
item.Domain.Equals(this.HttpContext.Request.Host.Host, StringComparison.InvariantCultureIgnoreCase));
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace BTCPayServer.Controllers
|
|||
{
|
||||
public class UIHomeController : Controller
|
||||
{
|
||||
private readonly ISettingsRepository _settingsRepository;
|
||||
private readonly ThemeSettings _theme;
|
||||
private readonly StoreRepository _storeRepository;
|
||||
private readonly BTCPayNetworkProvider _networkProvider;
|
||||
private IHttpClientFactory HttpClientFactory { get; }
|
||||
|
@ -47,13 +47,13 @@ namespace BTCPayServer.Controllers
|
|||
public LanguageService LanguageService { get; }
|
||||
|
||||
public UIHomeController(IHttpClientFactory httpClientFactory,
|
||||
ISettingsRepository settingsRepository,
|
||||
ThemeSettings theme,
|
||||
LanguageService languageService,
|
||||
StoreRepository storeRepository,
|
||||
BTCPayNetworkProvider networkProvider,
|
||||
SignInManager<ApplicationUser> signInManager)
|
||||
{
|
||||
_settingsRepository = settingsRepository;
|
||||
_theme = theme;
|
||||
HttpClientFactory = httpClientFactory;
|
||||
LanguageService = languageService;
|
||||
_networkProvider = networkProvider;
|
||||
|
@ -71,7 +71,7 @@ namespace BTCPayServer.Controllers
|
|||
[DomainMappingConstraint]
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
if ((await _settingsRepository.GetTheme()).FirstRun)
|
||||
if (_theme.FirstRun)
|
||||
{
|
||||
return RedirectToAction(nameof(UIAccountController.Register), "UIAccount");
|
||||
}
|
||||
|
|
|
@ -121,10 +121,9 @@ namespace BTCPayServer.Controllers
|
|||
|
||||
[Route("server/users/new")]
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> CreateUser()
|
||||
public IActionResult CreateUser()
|
||||
{
|
||||
ViewData["AllowRequestEmailConfirmation"] = (await _SettingsRepository.GetPolicies()).RequiresConfirmedEmail;
|
||||
|
||||
ViewData["AllowRequestEmailConfirmation"] = _policiesSettings.RequiresConfirmedEmail;
|
||||
return View();
|
||||
}
|
||||
|
||||
|
@ -132,7 +131,7 @@ namespace BTCPayServer.Controllers
|
|||
[HttpPost]
|
||||
public async Task<IActionResult> CreateUser(RegisterFromAdminViewModel model)
|
||||
{
|
||||
var requiresConfirmedEmail = (await _SettingsRepository.GetPolicies()).RequiresConfirmedEmail;
|
||||
var requiresConfirmedEmail = _policiesSettings.RequiresConfirmedEmail;
|
||||
ViewData["AllowRequestEmailConfirmation"] = requiresConfirmedEmail;
|
||||
if (!_Options.CheatMode)
|
||||
model.IsAdmin = false;
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace BTCPayServer.Controllers
|
|||
private readonly UserManager<ApplicationUser> _UserManager;
|
||||
private readonly UserService _userService;
|
||||
readonly SettingsRepository _SettingsRepository;
|
||||
readonly PoliciesSettings _policiesSettings;
|
||||
private readonly NBXplorerDashboard _dashBoard;
|
||||
private readonly StoreRepository _StoreRepository;
|
||||
readonly LightningConfigurationProvider _LnConfigProvider;
|
||||
|
@ -70,6 +71,7 @@ namespace BTCPayServer.Controllers
|
|||
IEnumerable<IStorageProviderService> storageProviderServices,
|
||||
BTCPayServerOptions options,
|
||||
SettingsRepository settingsRepository,
|
||||
PoliciesSettings policiesSettings,
|
||||
NBXplorerDashboard dashBoard,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
LightningConfigurationProvider lnConfigProvider,
|
||||
|
@ -81,6 +83,7 @@ namespace BTCPayServer.Controllers
|
|||
IOptions<ExternalServicesOptions> externalServiceOptions,
|
||||
Logs logs)
|
||||
{
|
||||
_policiesSettings = policiesSettings;
|
||||
_Options = options;
|
||||
_StoredFileRepository = storedFileRepository;
|
||||
_FileService = fileService;
|
||||
|
@ -278,10 +281,9 @@ namespace BTCPayServer.Controllers
|
|||
[Route("server/policies")]
|
||||
public async Task<IActionResult> Policies()
|
||||
{
|
||||
var data = (await _SettingsRepository.GetSettingAsync<PoliciesSettings>()) ?? new PoliciesSettings();
|
||||
ViewBag.AppsList = await GetAppSelectList();
|
||||
ViewBag.UpdateUrlPresent = _Options.UpdateUrl != null;
|
||||
return View(data);
|
||||
return View(_policiesSettings);
|
||||
}
|
||||
|
||||
[Route("server/policies")]
|
||||
|
@ -358,7 +360,7 @@ namespace BTCPayServer.Controllers
|
|||
Link = this.Request.GetAbsoluteUriNoPathBase(externalService.Value).AbsoluteUri
|
||||
});
|
||||
}
|
||||
if (await CanShowSSHService())
|
||||
if (CanShowSSHService())
|
||||
{
|
||||
result.OtherExternalServices.Add(new ServicesViewModel.OtherExternalService()
|
||||
{
|
||||
|
@ -845,7 +847,7 @@ namespace BTCPayServer.Controllers
|
|||
[HttpGet("server/services/ssh")]
|
||||
public async Task<IActionResult> SSHService()
|
||||
{
|
||||
if (!await CanShowSSHService())
|
||||
if (!CanShowSSHService())
|
||||
return NotFound();
|
||||
|
||||
var settings = _Options.SSHSettings;
|
||||
|
@ -881,10 +883,9 @@ namespace BTCPayServer.Controllers
|
|||
return View(vm);
|
||||
}
|
||||
|
||||
async Task<bool> CanShowSSHService()
|
||||
bool CanShowSSHService()
|
||||
{
|
||||
var policies = await _SettingsRepository.GetSettingAsync<PoliciesSettings>();
|
||||
return !(policies?.DisableSSHService is true) &&
|
||||
return !_policiesSettings.DisableSSHService &&
|
||||
_Options.SSHSettings != null && (_sshState.CanUseSSH || CanAccessAuthorizedKeyFile());
|
||||
}
|
||||
|
||||
|
@ -896,7 +897,7 @@ namespace BTCPayServer.Controllers
|
|||
[HttpPost("server/services/ssh")]
|
||||
public async Task<IActionResult> SSHService(SSHServiceViewModel viewModel, string? command = null)
|
||||
{
|
||||
if (!await CanShowSSHService())
|
||||
if (!CanShowSSHService())
|
||||
return NotFound();
|
||||
|
||||
if (command is "Save")
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace BTCPayServer.Controllers
|
|||
};
|
||||
|
||||
[HttpGet("{storeId}/lightning/{cryptoCode}")]
|
||||
public async Task<IActionResult> Lightning(string storeId, string cryptoCode)
|
||||
public IActionResult Lightning(string storeId, string cryptoCode)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
if (store == null)
|
||||
|
@ -43,7 +43,7 @@ namespace BTCPayServer.Controllers
|
|||
CryptoCode = cryptoCode,
|
||||
StoreId = storeId
|
||||
};
|
||||
await SetExistingValues(store, vm);
|
||||
SetExistingValues(store, vm);
|
||||
|
||||
if (vm.LightningNodeType == LightningNodeType.Internal)
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ namespace BTCPayServer.Controllers
|
|||
}
|
||||
|
||||
[HttpGet("{storeId}/lightning/{cryptoCode}/setup")]
|
||||
public async Task<IActionResult> SetupLightningNode(string storeId, string cryptoCode)
|
||||
public IActionResult SetupLightningNode(string storeId, string cryptoCode)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
if (store == null)
|
||||
|
@ -104,7 +104,7 @@ namespace BTCPayServer.Controllers
|
|||
CryptoCode = cryptoCode,
|
||||
StoreId = storeId
|
||||
};
|
||||
await SetExistingValues(store, vm);
|
||||
SetExistingValues(store, vm);
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ namespace BTCPayServer.Controllers
|
|||
if (store == null)
|
||||
return NotFound();
|
||||
|
||||
vm.CanUseInternalNode = await CanUseInternalLightning();
|
||||
vm.CanUseInternalNode = CanUseInternalLightning();
|
||||
|
||||
if (vm.CryptoCode == null)
|
||||
{
|
||||
|
@ -130,7 +130,7 @@ namespace BTCPayServer.Controllers
|
|||
LightningSupportedPaymentMethod? paymentMethod = null;
|
||||
if (vm.LightningNodeType == LightningNodeType.Internal)
|
||||
{
|
||||
if (!await CanUseInternalLightning())
|
||||
if (!CanUseInternalLightning())
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), "You are not authorized to use the internal lightning node");
|
||||
return View(vm);
|
||||
|
@ -213,7 +213,7 @@ namespace BTCPayServer.Controllers
|
|||
}
|
||||
|
||||
[HttpGet("{storeId}/lightning/{cryptoCode}/settings")]
|
||||
public async Task<IActionResult> LightningSettings(string storeId, string cryptoCode)
|
||||
public IActionResult LightningSettings(string storeId, string cryptoCode)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
if (store == null)
|
||||
|
@ -239,7 +239,7 @@ namespace BTCPayServer.Controllers
|
|||
LightningPrivateRouteHints = storeBlob.LightningPrivateRouteHints,
|
||||
OnChainWithLnInvoiceFallback = storeBlob.OnChainWithLnInvoiceFallback
|
||||
};
|
||||
await SetExistingValues(store, vm);
|
||||
SetExistingValues(store, vm);
|
||||
|
||||
if (lightning != null)
|
||||
{
|
||||
|
@ -360,14 +360,14 @@ namespace BTCPayServer.Controllers
|
|||
return RedirectToAction(nameof(LightningSettings), new { storeId, cryptoCode });
|
||||
}
|
||||
|
||||
private async Task<bool> CanUseInternalLightning()
|
||||
private bool CanUseInternalLightning()
|
||||
{
|
||||
return User.IsInRole(Roles.ServerAdmin) || (await _settingsRepository.GetPolicies()).AllowLightningInternalNodeForAll;
|
||||
return User.IsInRole(Roles.ServerAdmin) || _policiesSettings.AllowLightningInternalNodeForAll;
|
||||
}
|
||||
|
||||
private async Task SetExistingValues(StoreData store, LightningNodeViewModel vm)
|
||||
private void SetExistingValues(StoreData store, LightningNodeViewModel vm)
|
||||
{
|
||||
vm.CanUseInternalNode = await CanUseInternalLightning();
|
||||
vm.CanUseInternalNode = CanUseInternalLightning();
|
||||
var lightning = GetExistingLightningSupportedPaymentMethod(vm.CryptoCode, store);
|
||||
|
||||
if (lightning != null)
|
||||
|
|
|
@ -787,8 +787,7 @@ namespace BTCPayServer.Controllers
|
|||
|
||||
private async Task<(bool HotWallet, bool RPCImport)> CanUseHotWallet()
|
||||
{
|
||||
var policies = await _settingsRepository.GetSettingAsync<PoliciesSettings>();
|
||||
return await _authorizationService.CanUseHotWallet(policies, User);
|
||||
return await _authorizationService.CanUseHotWallet(_policiesSettings, User);
|
||||
}
|
||||
|
||||
private async Task<string> ReadAllText(IFormFile file)
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace BTCPayServer.Controllers
|
|||
ExplorerClientProvider explorerProvider,
|
||||
LanguageService langService,
|
||||
PaymentMethodHandlerDictionary paymentMethodHandlerDictionary,
|
||||
SettingsRepository settingsRepository,
|
||||
PoliciesSettings policiesSettings,
|
||||
IAuthorizationService authorizationService,
|
||||
EventAggregator eventAggregator,
|
||||
AppService appService,
|
||||
|
@ -72,7 +72,7 @@ namespace BTCPayServer.Controllers
|
|||
_TokenController = tokenController;
|
||||
_WalletProvider = walletProvider;
|
||||
_paymentMethodHandlerDictionary = paymentMethodHandlerDictionary;
|
||||
_settingsRepository = settingsRepository;
|
||||
_policiesSettings = policiesSettings;
|
||||
_authorizationService = authorizationService;
|
||||
_appService = appService;
|
||||
DataProtector = dataProtector.CreateProtector("ConfigProtector");
|
||||
|
@ -100,7 +100,7 @@ namespace BTCPayServer.Controllers
|
|||
private readonly ExplorerClientProvider _ExplorerProvider;
|
||||
private readonly LanguageService _LangService;
|
||||
private readonly PaymentMethodHandlerDictionary _paymentMethodHandlerDictionary;
|
||||
private readonly SettingsRepository _settingsRepository;
|
||||
private readonly PoliciesSettings _policiesSettings;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly AppService _appService;
|
||||
private readonly EventAggregator _EventAggregator;
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
using BTCPayServer.Services;
|
||||
|
||||
namespace BTCPayServer
|
||||
{
|
||||
public static class SettingsRepositoryExtensions
|
||||
{
|
||||
public static async Task<PoliciesSettings> GetPolicies(this ISettingsRepository settingsRepository)
|
||||
{
|
||||
return await settingsRepository.GetSettingAsync<PoliciesSettings>() ?? new PoliciesSettings();
|
||||
}
|
||||
public static async Task<ThemeSettings> GetTheme(this ISettingsRepository settingsRepository)
|
||||
{
|
||||
return await settingsRepository.GetSettingAsync<ThemeSettings>() ?? new ThemeSettings();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,8 +28,7 @@ namespace BTCPayServer.Filters
|
|||
{
|
||||
if (context.RouteContext.RouteData.Values.ContainsKey("appId"))
|
||||
return true;
|
||||
var settingsRepository = context.RouteContext.HttpContext.RequestServices.GetService<ISettingsRepository>();
|
||||
var policies = settingsRepository.GetPolicies().GetAwaiter().GetResult();
|
||||
var policies = context.RouteContext.HttpContext.RequestServices.GetService<PoliciesSettings>();
|
||||
if (policies?.DomainToAppMapping is { } mapping)
|
||||
{
|
||||
var matchedDomainMapping = mapping.FirstOrDefault(item =>
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace BTCPayServer.Filters
|
|||
|
||||
public bool Accept(ActionConstraintContext context)
|
||||
{
|
||||
return context.RouteContext.HttpContext.RequestServices.GetRequiredService<BTCPayServerEnvironment>().Experimental;
|
||||
return context.RouteContext.HttpContext.RequestServices.GetRequiredService<PoliciesSettings>().Experimental;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,7 +110,10 @@ namespace BTCPayServer.Hosting
|
|||
o.GetRequiredService<IOptions<BTCPayServerOptions>>().Value);
|
||||
// Don't move this StartupTask, we depend on it being right here
|
||||
services.AddStartupTask<MigrationStartupTask>();
|
||||
//
|
||||
//
|
||||
AddSettingsAccessor<PoliciesSettings>(services);
|
||||
AddSettingsAccessor<ThemeSettings>(services);
|
||||
//
|
||||
services.AddStartupTask<BlockExplorerLinkStartupTask>();
|
||||
services.TryAddSingleton<InvoiceRepository>();
|
||||
services.AddSingleton<PaymentService>();
|
||||
|
@ -477,6 +480,15 @@ namespace BTCPayServer.Hosting
|
|||
return services;
|
||||
}
|
||||
|
||||
private static void AddSettingsAccessor<T>(IServiceCollection services) where T : class, new()
|
||||
{
|
||||
services.TryAddSingleton<ISettingsAccessor<T>, SettingsAccessor<T>>();
|
||||
services.AddSingleton<IHostedService>(provider => (SettingsAccessor<T>)provider.GetRequiredService<ISettingsAccessor<T>>());
|
||||
services.AddSingleton<IStartupTask>(provider => (SettingsAccessor<T>)provider.GetRequiredService<ISettingsAccessor<T>>());
|
||||
// Singletons shouldn't reference the settings directly, but ISettingsAccessor<T>, since singletons won't have refreshed values of the setting
|
||||
services.AddTransient<T>(provider => provider.GetRequiredService<ISettingsAccessor<T>>().Settings);
|
||||
}
|
||||
|
||||
public static void SkipModelValidation<T>(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<SkippableObjectValidatorProvider.ISkipValidation, SkippableObjectValidatorProvider.SkipValidationType<T>>();
|
||||
|
|
|
@ -35,7 +35,6 @@ namespace BTCPayServer.Services
|
|||
NetworkType = provider.NetworkType;
|
||||
this.torServices = torServices;
|
||||
CheatMode = opts.CheatMode;
|
||||
Experimental = opts.Experimental;
|
||||
}
|
||||
public IWebHostEnvironment Environment
|
||||
{
|
||||
|
@ -81,8 +80,6 @@ namespace BTCPayServer.Services
|
|||
|
||||
public HttpContext Context => httpContext.HttpContext;
|
||||
|
||||
public bool Experimental { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder txt = new StringBuilder();
|
||||
|
|
|
@ -11,14 +11,15 @@ public class DefaultSwaggerProvider: ISwaggerProvider
|
|||
{
|
||||
private readonly IFileProvider _fileProvider;
|
||||
|
||||
public DefaultSwaggerProvider(IWebHostEnvironment webHostEnvironment, BTCPayServerEnvironment env)
|
||||
public DefaultSwaggerProvider(IWebHostEnvironment webHostEnvironment, ISettingsAccessor<PoliciesSettings> policies)
|
||||
{
|
||||
|
||||
_fileProvider = webHostEnvironment.WebRootFileProvider;
|
||||
Env = env;
|
||||
Policies = policies;
|
||||
}
|
||||
|
||||
public BTCPayServerEnvironment Env { get; }
|
||||
public ISettingsAccessor<PoliciesSettings> Policies { get; }
|
||||
|
||||
public async Task<JObject> Fetch()
|
||||
{
|
||||
|
@ -30,7 +31,7 @@ public class DefaultSwaggerProvider: ISwaggerProvider
|
|||
await using var stream = fi.CreateReadStream();
|
||||
using var reader = new StreamReader(fi.CreateReadStream());
|
||||
var jObject = JObject.Parse(await reader.ReadToEndAsync());
|
||||
if (jObject.Remove("x_experimental") && !Env.Experimental)
|
||||
if (jObject.Remove("x_experimental") && !Policies.Settings.Experimental)
|
||||
continue;
|
||||
json.Merge(jObject);
|
||||
}
|
||||
|
|
55
BTCPayServer/Services/ISettingsAccessor.cs
Normal file
55
BTCPayServer/Services/ISettingsAccessor.cs
Normal file
|
@ -0,0 +1,55 @@
|
|||
#nullable enable
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
using BTCPayServer.Events;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Services
|
||||
{
|
||||
public interface ISettingsAccessor<T>
|
||||
{
|
||||
T Settings { get; }
|
||||
}
|
||||
class SettingsAccessor<T> : ISettingsAccessor<T>, IStartupTask, IHostedService where T : class, new()
|
||||
{
|
||||
T? _Settings;
|
||||
public T Settings => _Settings ?? throw new InvalidOperationException($"Settings {typeof(T)} not yet initialized");
|
||||
|
||||
public EventAggregator Aggregator { get; }
|
||||
public ISettingsRepository SettingsRepository { get; }
|
||||
|
||||
IDisposable? disposable;
|
||||
|
||||
public SettingsAccessor(EventAggregator aggregator, ISettingsRepository settings)
|
||||
{
|
||||
Aggregator = aggregator;
|
||||
SettingsRepository = settings;
|
||||
}
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (_Settings != null)
|
||||
return;
|
||||
_Settings = await SettingsRepository.GetSettingAsync<T>() ?? new T();
|
||||
disposable = Aggregator.Subscribe<SettingsChanged<T>>(v => _Settings = Clone(v.Settings));
|
||||
}
|
||||
|
||||
private T Clone(T settings)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(settings))!;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
disposable?.Dispose();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
await StartAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ namespace BTCPayServer.Services.Mails
|
|||
{
|
||||
public class EmailSenderFactory
|
||||
{
|
||||
public ISettingsAccessor<PoliciesSettings> PoliciesSettings { get; }
|
||||
public Logs Logs { get; }
|
||||
|
||||
private readonly IBackgroundJobClient _jobClient;
|
||||
|
@ -15,23 +16,25 @@ namespace BTCPayServer.Services.Mails
|
|||
|
||||
public EmailSenderFactory(IBackgroundJobClient jobClient,
|
||||
SettingsRepository settingsSettingsRepository,
|
||||
ISettingsAccessor<PoliciesSettings> policiesSettings,
|
||||
StoreRepository storeRepository,
|
||||
Logs logs)
|
||||
{
|
||||
Logs = logs;
|
||||
_jobClient = jobClient;
|
||||
_settingsRepository = settingsSettingsRepository;
|
||||
PoliciesSettings = policiesSettings;
|
||||
_storeRepository = storeRepository;
|
||||
}
|
||||
|
||||
public async Task<IEmailSender> GetEmailSender(string storeId = null)
|
||||
public Task<IEmailSender> GetEmailSender(string storeId = null)
|
||||
{
|
||||
var serverSender = new ServerEmailSender(_settingsRepository, _jobClient, Logs);
|
||||
if (string.IsNullOrEmpty(storeId))
|
||||
return serverSender;
|
||||
return new StoreEmailSender(_storeRepository,
|
||||
!(await _settingsRepository.GetPolicies()).DisableStoresToUseServerEmailSettings ? serverSender : null, _jobClient,
|
||||
storeId, Logs);
|
||||
return Task.FromResult<IEmailSender>(serverSender);
|
||||
return Task.FromResult<IEmailSender>(new StoreEmailSender(_storeRepository,
|
||||
!PoliciesSettings.Settings.DisableStoresToUseServerEmailSettings ? serverSender : null, _jobClient,
|
||||
storeId, Logs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ namespace BTCPayServer.Services
|
|||
public List<BlockExplorerOverrideItem> BlockExplorerLinks { get; set; } = new List<BlockExplorerOverrideItem>();
|
||||
|
||||
public List<DomainToAppMappingItem> DomainToAppMapping { get; set; } = new List<DomainToAppMappingItem>();
|
||||
[Display(Name = "Enable experimental features")]
|
||||
public bool Experimental { get; set; }
|
||||
|
||||
public class BlockExplorerOverrideItem
|
||||
{
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
@using BTCPayServer.Abstractions.Contracts
|
||||
@inject ISettingsRepository _settingsRepository
|
||||
@inject BTCPayServer.Services.PoliciesSettings PoliciesSettings
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
@{ var policies = await _settingsRepository.GetPolicies(); }
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" href="~/favicon.ico" type="image/x-icon">
|
||||
@if (policies.DiscourageSearchEngines)
|
||||
@if (PoliciesSettings.DiscourageSearchEngines)
|
||||
{
|
||||
<meta name="robots" content="noindex">
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
@using BTCPayServer.Abstractions.Contracts
|
||||
@using BTCPayServer.Abstractions.Contracts
|
||||
@using BTCPayServer.Abstractions.Extensions
|
||||
@using BTCPayServer.Services
|
||||
@inject ISettingsRepository _settingsRepository
|
||||
@inject ThemeSettings Theme
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
@{ var theme = await _settingsRepository.GetTheme(); }
|
||||
|
||||
@if (theme.CustomTheme)
|
||||
@if (Theme.CustomTheme)
|
||||
{
|
||||
<link href="@Context.Request.GetRelativePathOrAbsolute(theme.CssUri)" rel="stylesheet" asp-append-version="true" />
|
||||
<link href="@Context.Request.GetRelativePathOrAbsolute(Theme.CssUri)" rel="stylesheet" asp-append-version="true" />
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
@inject BTCPayServer.Services.BTCPayServerEnvironment _env
|
||||
@inject SignInManager<ApplicationUser> _signInManager
|
||||
@inject UserManager<ApplicationUser> _userManager
|
||||
@inject ISettingsRepository _settingsRepository
|
||||
@inject LinkGenerator _linkGenerator
|
||||
@inject BTCPayServer.Services.PoliciesSettings PoliciesSettings
|
||||
|
||||
@{
|
||||
var notificationDisabled = (await _settingsRepository.GetPolicies()).DisableInstantNotifications;
|
||||
var notificationDisabled = PoliciesSettings.DisableInstantNotifications;
|
||||
if (!notificationDisabled)
|
||||
{
|
||||
var user = await _userManager.GetUserAsync(User);
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
@inject ISettingsRepository _settingsRepository
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
@inject BTCPayServer.Services.ThemeSettings Theme
|
||||
|
||||
@using BTCPayServer.Services.Apps
|
||||
@using BTCPayServer.Abstractions.Contracts
|
||||
@using BTCPayServer.Abstractions.Extensions
|
||||
@model BTCPayServer.Models.AppViewModels.ViewPointOfSaleViewModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = Model.Title;
|
||||
Layout = null;
|
||||
var theme = await _settingsRepository.GetTheme();
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
@ -22,7 +22,7 @@
|
|||
<link rel="apple-touch-startup-image" href="~/img/splash.png">
|
||||
<link rel="manifest" href="~/manifest.json">
|
||||
<bundle name="wwwroot/bundles/main-bundle.min.css" asp-append-version="true" />
|
||||
<link href="@Context.Request.GetRelativePathOrAbsolute(theme.CssUri)" rel="stylesheet" asp-append-version="true"/>
|
||||
<link href="@Context.Request.GetRelativePathOrAbsolute(Theme.CssUri)" rel="stylesheet" asp-append-version="true"/>
|
||||
@if (Model.CustomCSSLink != null)
|
||||
{
|
||||
<link href="@Model.CustomCSSLink" rel="stylesheet" />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@using BTCPayServer.Abstractions.Contracts
|
||||
@model LoginViewModel
|
||||
@inject ISettingsRepository _settingsRepository
|
||||
@inject BTCPayServer.Services.PoliciesSettings PoliciesSettings
|
||||
@{
|
||||
ViewData["Title"] = "Sign in";
|
||||
Layout = "_LayoutSignedOut";
|
||||
|
@ -35,7 +35,7 @@
|
|||
<form asp-action="LoginWithCode" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" id="logincode-form">
|
||||
<input asp-for="LoginCode" type="hidden" class="form-control"/>
|
||||
</form>
|
||||
@if (!(await _settingsRepository.GetPolicies()).LockSubscription)
|
||||
@if (!PoliciesSettings.LockSubscription)
|
||||
{
|
||||
<p class="text-center mt-2 mb-0">
|
||||
<a id="Register" style="font-size:1.15rem" asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]" tabindex="4">Create your account</a>
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
@inject ISettingsRepository SettingsRepository
|
||||
@using BTCPayServer.Abstractions.Contracts
|
||||
@using BTCPayServer.Models.AppViewModels
|
||||
@inject BTCPayServer.Services.ThemeSettings Theme
|
||||
@{
|
||||
ViewData["Title"] = Model.Title;
|
||||
Layout = null;
|
||||
var theme = await SettingsRepository.GetTheme();
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
@ -264,7 +264,7 @@
|
|||
</div>
|
||||
<div class="card-footer text-muted d-flex flex-wrap align-items-center">
|
||||
<div class="me-3" v-text="`Updated ${lastUpdated}`">Updated @Model.Info.LastUpdated</div>
|
||||
@if (!theme.CustomTheme)
|
||||
@if (!Theme.CustomTheme)
|
||||
{
|
||||
<vc:theme-switch css-class="text-muted me-3" responsive="none"/>
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
@inject BTCPayServer.Services.BTCPayServerEnvironment env
|
||||
@inject ISettingsRepository _settingsRepository
|
||||
@inject BTCPayServer.Services.ThemeSettings Theme
|
||||
@{
|
||||
ViewData["Title"] = Model.Title;
|
||||
Layout = null;
|
||||
var theme = await _settingsRepository.GetTheme();
|
||||
string StatusClass(InvoiceState state)
|
||||
{
|
||||
switch (state.Status.ToModernStatus())
|
||||
|
@ -365,7 +365,7 @@
|
|||
<span class="text-muted mx-2">
|
||||
Powered by <a href="https://btcpayserver.org" target="_blank" rel="noreferrer noopener">BTCPay Server</a>
|
||||
</span>
|
||||
@if (!theme.CustomTheme)
|
||||
@if (!Theme.CustomTheme)
|
||||
{
|
||||
<vc:theme-switch css-class="text-muted mx-2" responsive="none"/>
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
@using BTCPayServer.Abstractions.Extensions
|
||||
@using BTCPayServer.Lightning
|
||||
@model BTCPayServer.Controllers.ShowLightningNodeInfoViewModel
|
||||
@inject BTCPayServer.Services.ThemeSettings Theme
|
||||
@{
|
||||
Layout = null;
|
||||
var theme = await _settingsRepository.GetTheme();
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
@ -20,7 +20,7 @@
|
|||
<link rel="apple-touch-startup-image" href="~/img/splash.png" asp-append-version="true">
|
||||
<link rel="manifest" href="~/manifest.json">
|
||||
<bundle name="wwwroot/bundles/main-bundle.min.css" asp-append-version="true" />
|
||||
<link href="@Context.Request.GetRelativePathOrAbsolute(theme.CssUri)" rel="stylesheet" asp-append-version="true"/>
|
||||
<link href="@Context.Request.GetRelativePathOrAbsolute(Theme.CssUri)" rel="stylesheet" asp-append-version="true"/>
|
||||
<link href="~/main/qrcode.css" rel="stylesheet" asp-append-version="true" />
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
@inject BTCPayServer.Services.BTCPayServerEnvironment env
|
||||
@inject BTCPayServer.Services.ThemeSettings Theme
|
||||
|
||||
@using NUglify.Helpers
|
||||
@using BTCPayServer.Abstractions.Contracts
|
||||
@using BTCPayServer.Abstractions.Extensions
|
||||
@model BTCPayServer.Models.ViewPullPaymentModel
|
||||
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
@inject BTCPayServer.Services.BTCPayServerEnvironment env
|
||||
@inject ISettingsRepository _settingsRepository
|
||||
@{
|
||||
ViewData["Title"] = Model.Title;
|
||||
Layout = null;
|
||||
var theme = await _settingsRepository.GetTheme();
|
||||
string StatusTextClass(string status)
|
||||
{
|
||||
switch (status)
|
||||
|
@ -196,7 +196,7 @@
|
|||
<span class="text-muted mx-2">
|
||||
Powered by <a href="https://btcpayserver.org" target="_blank" rel="noreferrer noopener">BTCPay Server</a>
|
||||
</span>
|
||||
@if (!theme.CustomTheme)
|
||||
@if (!Theme.CustomTheme)
|
||||
{
|
||||
<vc:theme-switch css-class="text-muted mx-2" responsive="none"/>
|
||||
}
|
||||
|
|
|
@ -111,6 +111,10 @@
|
|||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<span asp-validation-for="DiscourageSearchEngines" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-check my-3">
|
||||
<input asp-for="Experimental" type="checkbox" class="form-check-input"/>
|
||||
<label asp-for="Experimental" class="form-check-label"></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue