Hide LN Balance when using internal node and not server admin (#5639)

* Hide LN Balance when using internal node and not server admin

* Minor updates

---------

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
This commit is contained in:
Andrew Camilleri 2024-01-06 08:46:19 +01:00 committed by GitHub
parent 78882dcff0
commit e90414bded
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 11 deletions

View file

@ -1,5 +1,8 @@
@model BTCPayServer.Components.StoreLightningBalance.StoreLightningBalanceViewModel @model BTCPayServer.Components.StoreLightningBalance.StoreLightningBalanceViewModel
@if(!Model.InitialRendering && Model.Balance == null)
{
return;
}
<div id="StoreLightningBalance-@Model.Store.Id" class="widget store-lightning-balance"> <div id="StoreLightningBalance-@Model.Store.Id" class="widget store-lightning-balance">
<div class="d-flex gap-3 align-items-center justify-content-between mb-2"> <div class="d-flex gap-3 align-items-center justify-content-between mb-2">
<h6>Lightning Balance</h6> <h6>Lightning Balance</h6>

View file

@ -2,6 +2,7 @@ using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Abstractions.Extensions; using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Client;
using BTCPayServer.Configuration; using BTCPayServer.Configuration;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Lightning; using BTCPayServer.Lightning;
@ -9,9 +10,11 @@ using BTCPayServer.Models;
using BTCPayServer.Models.StoreViewModels; using BTCPayServer.Models.StoreViewModels;
using BTCPayServer.Payments; using BTCPayServer.Payments;
using BTCPayServer.Payments.Lightning; using BTCPayServer.Payments.Lightning;
using BTCPayServer.Security;
using BTCPayServer.Services; using BTCPayServer.Services;
using BTCPayServer.Services.Rates; using BTCPayServer.Services.Rates;
using BTCPayServer.Services.Stores; using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -26,6 +29,7 @@ public class StoreLightningBalance : ViewComponent
private readonly LightningClientFactoryService _lightningClientFactory; private readonly LightningClientFactoryService _lightningClientFactory;
private readonly IOptions<LightningNetworkOptions> _lightningNetworkOptions; private readonly IOptions<LightningNetworkOptions> _lightningNetworkOptions;
private readonly IOptions<ExternalServicesOptions> _externalServiceOptions; private readonly IOptions<ExternalServicesOptions> _externalServiceOptions;
private readonly IAuthorizationService _authorizationService;
public StoreLightningBalance( public StoreLightningBalance(
StoreRepository storeRepo, StoreRepository storeRepo,
@ -34,13 +38,15 @@ public class StoreLightningBalance : ViewComponent
BTCPayServerOptions btcpayServerOptions, BTCPayServerOptions btcpayServerOptions,
LightningClientFactoryService lightningClientFactory, LightningClientFactoryService lightningClientFactory,
IOptions<LightningNetworkOptions> lightningNetworkOptions, IOptions<LightningNetworkOptions> lightningNetworkOptions,
IOptions<ExternalServicesOptions> externalServiceOptions) IOptions<ExternalServicesOptions> externalServiceOptions,
IAuthorizationService authorizationService)
{ {
_storeRepo = storeRepo; _storeRepo = storeRepo;
_currencies = currencies; _currencies = currencies;
_networkProvider = networkProvider; _networkProvider = networkProvider;
_btcpayServerOptions = btcpayServerOptions; _btcpayServerOptions = btcpayServerOptions;
_externalServiceOptions = externalServiceOptions; _externalServiceOptions = externalServiceOptions;
_authorizationService = authorizationService;
_lightningClientFactory = lightningClientFactory; _lightningClientFactory = lightningClientFactory;
_lightningNetworkOptions = lightningNetworkOptions; _lightningNetworkOptions = lightningNetworkOptions;
} }
@ -55,12 +61,18 @@ public class StoreLightningBalance : ViewComponent
vm.DefaultCurrency = vm.Store.GetStoreBlob().DefaultCurrency; vm.DefaultCurrency = vm.Store.GetStoreBlob().DefaultCurrency;
vm.CurrencyData = _currencies.GetCurrencyData(vm.DefaultCurrency, true); vm.CurrencyData = _currencies.GetCurrencyData(vm.DefaultCurrency, true);
try
{
var lightningClient = await GetLightningClient(vm.Store, vm.CryptoCode);
if (lightningClient == null)
{
vm.InitialRendering = false;
return View(vm);
}
if (vm.InitialRendering) if (vm.InitialRendering)
return View(vm); return View(vm);
try
{
var lightningClient = GetLightningClient(vm.Store, vm.CryptoCode);
var balance = await lightningClient.GetBalance(); var balance = await lightningClient.GetBalance();
vm.Balance = balance; vm.Balance = balance;
vm.TotalOnchain = balance.OnchainBalance != null vm.TotalOnchain = balance.OnchainBalance != null
@ -72,7 +84,8 @@ public class StoreLightningBalance : ViewComponent
(balance.OffchainBalance.Closing ?? 0) (balance.OffchainBalance.Closing ?? 0)
: null; : null;
} }
catch (NotSupportedException)
catch (Exception ex) when (ex is NotImplementedException or NotSupportedException)
{ {
// not all implementations support balance fetching // not all implementations support balance fetching
vm.ProblemDescription = "Your node does not support balance fetching."; vm.ProblemDescription = "Your node does not support balance fetching.";
@ -85,7 +98,7 @@ public class StoreLightningBalance : ViewComponent
return View(vm); return View(vm);
} }
private ILightningClient GetLightningClient(StoreData store, string cryptoCode) private async Task<ILightningClient> GetLightningClient(StoreData store, string cryptoCode )
{ {
var network = _networkProvider.GetNetwork<BTCPayNetwork>(cryptoCode); var network = _networkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
var id = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike); var id = new PaymentMethodId(cryptoCode, PaymentTypes.LightningLike);
@ -101,7 +114,9 @@ public class StoreLightningBalance : ViewComponent
} }
if (existing.IsInternalNode && _lightningNetworkOptions.Value.InternalLightningByCryptoCode.TryGetValue(cryptoCode, out var internalLightningNode)) if (existing.IsInternalNode && _lightningNetworkOptions.Value.InternalLightningByCryptoCode.TryGetValue(cryptoCode, out var internalLightningNode))
{ {
return internalLightningNode; var result = await _authorizationService.AuthorizeAsync(HttpContext.User, null,
new PolicyRequirement(Policies.CanUseInternalLightningNode));
return result.Succeeded ? internalLightningNode : null;
} }
return null; return null;

View file

@ -7,6 +7,7 @@
@using BTCPayServer.Components.AppSales @using BTCPayServer.Components.AppSales
@using BTCPayServer.Components.AppTopItems @using BTCPayServer.Components.AppTopItems
@using BTCPayServer.Services.Apps @using BTCPayServer.Services.Apps
@using BTCPayServer.Client
@model StoreDashboardViewModel @model StoreDashboardViewModel
@{ @{
ViewData.SetActivePage(StoreNavPages.Dashboard, Model.StoreName, Model.StoreId); ViewData.SetActivePage(StoreNavPages.Dashboard, Model.StoreName, Model.StoreId);
@ -82,7 +83,7 @@
@if (Model.LightningEnabled) @if (Model.LightningEnabled)
{ {
<vc:store-lightning-balance vm="@(new StoreLightningBalanceViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })"/> <vc:store-lightning-balance vm="@(new StoreLightningBalanceViewModel { Store = store, CryptoCode = Model.CryptoCode, InitialRendering = true })"/>
<vc:store-lightning-services vm="@(new StoreLightningServicesViewModel { Store = store, CryptoCode = Model.CryptoCode })"/> <vc:store-lightning-services vm="@(new StoreLightningServicesViewModel { Store = store, CryptoCode = Model.CryptoCode })" permission="@Policies.CanModifyServerSettings"/>
} }
@if (Model.WalletEnabled) @if (Model.WalletEnabled)
{ {