mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-20 13:34:37 +01:00
Suppoort macaroonfilepath in connection string
This commit is contained in:
parent
73cb3dc4ee
commit
1a1078782e
7 changed files with 162 additions and 32 deletions
|
@ -59,6 +59,14 @@ namespace BTCPayServer.Tests.Lnd
|
|||
Assert.Equal(createInvoice.BOLT11, getInvoice.BOLT11);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Play()
|
||||
{
|
||||
var seq = new System.Buffers.ReadOnlySequence<byte>(new ReadOnlyMemory<byte>(new byte[1000]));
|
||||
var seq2 = seq.Slice(3);
|
||||
var pos = seq2.GetPosition(0);
|
||||
}
|
||||
|
||||
// integration tests
|
||||
[Fact]
|
||||
public async Task TestWaitListenInvoice()
|
||||
|
|
|
@ -97,6 +97,20 @@ namespace BTCPayServer.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
if(connectionString.MacaroonFilePath != null)
|
||||
{
|
||||
if(!CanUseInternalLightning())
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), "You are not authorized to use macaroonfilepath");
|
||||
return View(vm);
|
||||
}
|
||||
if(!System.IO.File.Exists(connectionString.MacaroonFilePath))
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), "The macaroonfilepath file does exist");
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
|
||||
if (isInternalNode && !CanUseInternalLightning())
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.ConnectionString), "Unauthorized url");
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
return new LndInvoiceClient(new LndSwaggerClient(new LndRestSettings(connString.BaseUri)
|
||||
{
|
||||
Macaroon = connString.Macaroon,
|
||||
MacaroonFilePath = connString.MacaroonFilePath,
|
||||
CertificateThumbprint = connString.CertificateThumbprint,
|
||||
AllowInsecure = connString.AllowInsecure,
|
||||
}));
|
||||
|
|
|
@ -196,6 +196,22 @@ namespace BTCPayServer.Payments.Lightning
|
|||
}
|
||||
}
|
||||
|
||||
var macaroonFilePath = Take(keyValues, "macaroonfilepath");
|
||||
if (macaroonFilePath != null)
|
||||
{
|
||||
if(macaroon != null)
|
||||
{
|
||||
error = $"The key 'macaroon' is already specified";
|
||||
return false;
|
||||
}
|
||||
if(!macaroonFilePath.EndsWith(".macaroon", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
error = $"The key 'macaroonfilepath' should point to a .macaroon file";
|
||||
return false;
|
||||
}
|
||||
result.MacaroonFilePath = macaroonFilePath;
|
||||
}
|
||||
|
||||
string securitySet = null;
|
||||
var certthumbprint = Take(keyValues, "certthumbprint");
|
||||
if (certthumbprint != null)
|
||||
|
@ -223,12 +239,12 @@ namespace BTCPayServer.Payments.Lightning
|
|||
if (allowinsecureStr != null)
|
||||
{
|
||||
var allowedValues = new[] { "true", "false" };
|
||||
if(!allowedValues.Any(v=> v.Equals(allowinsecureStr, StringComparison.OrdinalIgnoreCase)))
|
||||
if (!allowedValues.Any(v => v.Equals(allowinsecureStr, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
error = $"The key 'allowinsecure' should be true or false";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool allowInsecure = allowinsecureStr.Equals("true", StringComparison.OrdinalIgnoreCase);
|
||||
if (securitySet != null && allowInsecure)
|
||||
{
|
||||
|
@ -238,7 +254,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
result.AllowInsecure = allowInsecure;
|
||||
}
|
||||
|
||||
if(!result.AllowInsecure && result.BaseUri.Scheme == "http")
|
||||
if (!result.AllowInsecure && result.BaseUri.Scheme == "http")
|
||||
{
|
||||
error = $"The key 'allowinsecure' is false, but server's Uri is not using https";
|
||||
return false;
|
||||
|
@ -340,6 +356,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
private set;
|
||||
}
|
||||
public byte[] Macaroon { get; set; }
|
||||
public string MacaroonFilePath { get; set; }
|
||||
public byte[] CertificateThumbprint { get; set; }
|
||||
public bool AllowInsecure { get; set; }
|
||||
|
||||
|
@ -388,11 +405,15 @@ namespace BTCPayServer.Payments.Lightning
|
|||
{
|
||||
builder.Append($";macaroon={Encoder.EncodeData(Macaroon)}");
|
||||
}
|
||||
if (MacaroonFilePath != null)
|
||||
{
|
||||
builder.Append($";macaroonfilepath={MacaroonFilePath}");
|
||||
}
|
||||
if (CertificateThumbprint != null)
|
||||
{
|
||||
builder.Append($";certthumbprint={Encoders.Hex.EncodeData(CertificateThumbprint)}");
|
||||
}
|
||||
if(AllowInsecure)
|
||||
if (AllowInsecure)
|
||||
{
|
||||
builder.Append($";allowinsecure=true");
|
||||
}
|
||||
|
|
67
BTCPayServer/Payments/Lightning/Lnd/LndAuthentication.cs
Normal file
67
BTCPayServer/Payments/Lightning/Lnd/LndAuthentication.cs
Normal file
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using NBitcoin.DataEncoders;
|
||||
|
||||
namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
{
|
||||
public abstract class LndAuthentication
|
||||
{
|
||||
public class FixedMacaroonAuthentication : LndAuthentication
|
||||
{
|
||||
public FixedMacaroonAuthentication(byte[] macaroon)
|
||||
{
|
||||
if (macaroon == null)
|
||||
throw new ArgumentNullException(nameof(macaroon));
|
||||
Macaroon = macaroon;
|
||||
}
|
||||
public byte[] Macaroon { get; set; }
|
||||
public override void AddAuthentication(HttpRequestMessage httpRequest)
|
||||
{
|
||||
httpRequest.Headers.Add("Grpc-Metadata-macaroon", Encoders.Hex.EncodeData(Macaroon));
|
||||
}
|
||||
}
|
||||
public class NullAuthentication : LndAuthentication
|
||||
{
|
||||
public static NullAuthentication Instance { get; } = new NullAuthentication();
|
||||
|
||||
private NullAuthentication()
|
||||
{
|
||||
|
||||
}
|
||||
public override void AddAuthentication(HttpRequestMessage httpRequest)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class MacaroonFileAuthentication : LndAuthentication
|
||||
{
|
||||
public MacaroonFileAuthentication(string filePath)
|
||||
{
|
||||
if (filePath == null)
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
// Because this dump the whole file, let's make sure it is indeed the macaroon
|
||||
if (!filePath.EndsWith(".macaroon", StringComparison.OrdinalIgnoreCase))
|
||||
throw new ArgumentException(message: "filePath is not a macaroon file", paramName: nameof(filePath));
|
||||
FilePath = filePath;
|
||||
}
|
||||
public string FilePath { get; set; }
|
||||
public override void AddAuthentication(HttpRequestMessage httpRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bytes = File.ReadAllBytes(FilePath);
|
||||
httpRequest.Headers.Add("Grpc-Metadata-macaroon", Encoders.Hex.EncodeData(bytes));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void AddAuthentication(HttpRequestMessage httpRequest);
|
||||
}
|
||||
}
|
36
BTCPayServer/Payments/Lightning/Lnd/LndRestSettings.cs
Normal file
36
BTCPayServer/Payments/Lightning/Lnd/LndRestSettings.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
{
|
||||
public class LndRestSettings
|
||||
{
|
||||
public LndRestSettings()
|
||||
{
|
||||
|
||||
}
|
||||
public LndRestSettings(Uri uri)
|
||||
{
|
||||
Uri = uri;
|
||||
}
|
||||
public Uri Uri { get; set; }
|
||||
/// <summary>
|
||||
/// The SHA256 of the PEM certificate
|
||||
/// </summary>
|
||||
public byte[] CertificateThumbprint { get; set; }
|
||||
public byte[] Macaroon { get; set; }
|
||||
public bool AllowInsecure { get; set; }
|
||||
public string MacaroonFilePath { get; set; }
|
||||
|
||||
public LndAuthentication CreateLndAuthentication()
|
||||
{
|
||||
if (Macaroon != null)
|
||||
return new LndAuthentication.FixedMacaroonAuthentication(Macaroon);
|
||||
if (!string.IsNullOrEmpty(MacaroonFilePath))
|
||||
return new LndAuthentication.MacaroonFileAuthentication(MacaroonFilePath);
|
||||
return LndAuthentication.NullAuthentication.Instance;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,38 +10,28 @@ using System.Security.Cryptography.X509Certificates;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NBitcoin.DataEncoders;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Payments.Lightning.Lnd
|
||||
{
|
||||
public class LndRestSettings
|
||||
{
|
||||
public LndRestSettings()
|
||||
{
|
||||
|
||||
}
|
||||
public LndRestSettings(Uri uri)
|
||||
{
|
||||
Uri = uri;
|
||||
}
|
||||
public Uri Uri { get; set; }
|
||||
/// <summary>
|
||||
/// The SHA256 of the PEM certificate
|
||||
/// </summary>
|
||||
public byte[] CertificateThumbprint { get; set; }
|
||||
public byte[] Macaroon { get; set; }
|
||||
public bool AllowInsecure { get; set; }
|
||||
}
|
||||
|
||||
public partial class LndSwaggerClient
|
||||
{
|
||||
public LndSwaggerClient(LndRestSettings settings)
|
||||
: this(settings.Uri.AbsoluteUri.TrimEnd('/'), CreateHttpClient(settings))
|
||||
{
|
||||
_Settings = settings;
|
||||
_Authentication = settings.CreateLndAuthentication();
|
||||
}
|
||||
LndRestSettings _Settings;
|
||||
LndAuthentication _Authentication;
|
||||
|
||||
partial void PrepareRequest(HttpClient client, HttpRequestMessage request, string url)
|
||||
{
|
||||
_Authentication.AddAuthentication(request);
|
||||
}
|
||||
|
||||
internal static HttpClient CreateHttpClient(LndRestSettings settings)
|
||||
{
|
||||
var handler = new HttpClientHandler
|
||||
|
@ -60,7 +50,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd
|
|||
};
|
||||
}
|
||||
|
||||
if(settings.AllowInsecure)
|
||||
if (settings.AllowInsecure)
|
||||
{
|
||||
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
|
||||
}
|
||||
|
@ -69,14 +59,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd
|
|||
if (settings.Uri.Scheme == "http")
|
||||
throw new InvalidOperationException("AllowInsecure is set to false, but the URI is not using https");
|
||||
}
|
||||
|
||||
var httpClient = new HttpClient(handler);
|
||||
if (settings.Macaroon != null)
|
||||
{
|
||||
var macaroonHex = BitConverter.ToString(settings.Macaroon).Replace("-", "", StringComparison.InvariantCulture);
|
||||
httpClient.DefaultRequestHeaders.Add("Grpc-Metadata-macaroon", macaroonHex);
|
||||
}
|
||||
return httpClient;
|
||||
return new HttpClient(handler);
|
||||
}
|
||||
|
||||
internal HttpClient CreateHttpClient()
|
||||
|
|
Loading…
Add table
Reference in a new issue