mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 06:21:44 +01:00
.NET 2.0sify, use the same configuration framework as NBXplorer
This commit is contained in:
parent
99ae549c24
commit
ce055dece9
16 changed files with 465 additions and 584 deletions
|
@ -77,10 +77,10 @@ namespace BTCPayServer.Tests
|
|||
|
||||
ServerUri = new Uri("http://127.0.0.1:" + port + "/");
|
||||
|
||||
BTCPayServerOptions options = new BTCPayServerOptions();
|
||||
options.LoadArgs(new TextFileConfiguration(new string[] { "-datadir", _Directory }));
|
||||
var conf = new DefaultConfiguration() { Logger = Logs.LogProvider.CreateLogger("Console") }.CreateConfiguration(new[] { "--datadir", _Directory });
|
||||
|
||||
_Host = new WebHostBuilder()
|
||||
.UseConfiguration(conf)
|
||||
.ConfigureServices(s =>
|
||||
{
|
||||
s.AddSingleton<IRateProvider>(new MockRateProvider(new Rate("USD", 5000m)));
|
||||
|
@ -91,7 +91,6 @@ namespace BTCPayServer.Tests
|
|||
.AddProvider(Logs.LogProvider);
|
||||
});
|
||||
})
|
||||
.AddPayServer(options)
|
||||
.UseKestrel()
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace BTCPayServer.Tests
|
|||
config.AppendLine($"rpc.auth={Node.AuthenticationString}");
|
||||
config.AppendLine($"node.endpoint={Node.NodeEndpoint.Address}:{Node.NodeEndpoint.Port}");
|
||||
File.WriteAllText(Path.Combine(launcher2.CurrentDirectory, "settings.config"), config.ToString());
|
||||
_Process = launcher.Start("dotnet", $"NBXplorer.dll -datadir \"{launcher2.CurrentDirectory}\"");
|
||||
_Process = launcher.Start("dotnet", $"NBXplorer.dll --datadir \"{launcher2.CurrentDirectory}\"");
|
||||
ExplorerClient = new NBXplorer.ExplorerClient(Node.Network, new Uri($"http://127.0.0.1:{port}/"));
|
||||
CookieFile = Path.Combine(launcher2.CurrentDirectory, ".cookie");
|
||||
File.Create(CookieFile).Close(); //Will be wipedout when the client starts
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
<PackageReference Include="NBitpayClient" Version="1.0.0.6" />
|
||||
<PackageReference Include="DBreeze" Version="1.87.0" />
|
||||
<PackageReference Include="NBXplorer.Client" Version="1.0.0.12" />
|
||||
<PackageReference Include="NicolasDorier.CommandLine" Version="1.0.0.1" />
|
||||
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.1" />
|
||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.9" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
|
||||
<PackageReference Include="System.Xml.XmlSerializer" Version="4.0.11" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -7,6 +7,8 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using StandardConfiguration;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace BTCPayServer.Configuration
|
||||
{
|
||||
|
@ -41,75 +43,20 @@ namespace BTCPayServer.Configuration
|
|||
set;
|
||||
}
|
||||
|
||||
public void LoadArgs(TextFileConfiguration consoleConfig)
|
||||
public void LoadArgs(IConfiguration conf)
|
||||
{
|
||||
ConfigurationFile = consoleConfig.GetOrDefault<string>("conf", null);
|
||||
DataDir = consoleConfig.GetOrDefault<string>("datadir", null);
|
||||
if(DataDir != null && ConfigurationFile != null)
|
||||
{
|
||||
var isRelativePath = Path.GetFullPath(ConfigurationFile).Length > ConfigurationFile.Length;
|
||||
if(isRelativePath)
|
||||
{
|
||||
ConfigurationFile = Path.Combine(DataDir, ConfigurationFile);
|
||||
}
|
||||
}
|
||||
|
||||
Network = consoleConfig.GetOrDefault<bool>("testnet", false) ? Network.TestNet :
|
||||
consoleConfig.GetOrDefault<bool>("regtest", false) ? Network.RegTest :
|
||||
null;
|
||||
|
||||
if(DataDir != null && ConfigurationFile == null)
|
||||
{
|
||||
ConfigurationFile = GetDefaultConfigurationFile(Network != null);
|
||||
}
|
||||
|
||||
if(ConfigurationFile != null)
|
||||
{
|
||||
AssetConfigFileExists();
|
||||
var configTemp = TextFileConfiguration.Parse(File.ReadAllText(ConfigurationFile));
|
||||
Network = Network ?? (configTemp.GetOrDefault<bool>("testnet", false) ? Network.TestNet :
|
||||
configTemp.GetOrDefault<bool>("regtest", false) ? Network.RegTest :
|
||||
null);
|
||||
}
|
||||
|
||||
Network = Network ?? Network.Main;
|
||||
if(DataDir == null)
|
||||
{
|
||||
DataDir = DefaultDataDirectory.GetDefaultDirectory("BTCPayServer", Network, true);
|
||||
ConfigurationFile = GetDefaultConfigurationFile(true);
|
||||
}
|
||||
|
||||
if(!Directory.Exists(DataDir))
|
||||
throw new ConfigurationException("Data directory does not exists");
|
||||
|
||||
var config = TextFileConfiguration.Parse(File.ReadAllText(ConfigurationFile));
|
||||
consoleConfig.MergeInto(config, true);
|
||||
var networkInfo = DefaultConfiguration.GetNetwork(conf);
|
||||
Network = networkInfo?.Network;
|
||||
if(Network == null)
|
||||
throw new ConfigException("Invalid network");
|
||||
|
||||
DataDir = conf.GetOrDefault<string>("datadir", networkInfo.DefaultDataDirectory);
|
||||
Logs.Configuration.LogInformation("Network: " + Network);
|
||||
Logs.Configuration.LogInformation("Data directory set to " + DataDir);
|
||||
Logs.Configuration.LogInformation("Configuration file set to " + ConfigurationFile);
|
||||
|
||||
var defaultPort = config.GetOrDefault<int>("port", GetDefaultPort(Network));
|
||||
Listen = config
|
||||
.GetAll("bind")
|
||||
.Select(p => ConvertToEndpoint(p, defaultPort))
|
||||
.ToList();
|
||||
if(Listen.Count == 0)
|
||||
{
|
||||
Listen.Add(new IPEndPoint(IPAddress.Parse("127.0.0.1"), defaultPort));
|
||||
}
|
||||
|
||||
Explorer = config.GetOrDefault<Uri>("explorer.url", GetDefaultNXplorerUri());
|
||||
CookieFile = config.GetOrDefault<string>("explorer.cookiefile", GetExplorerDefaultCookiePath());
|
||||
ExternalUrl = config.GetOrDefault<Uri>("externalurl", null);
|
||||
if(ExternalUrl == null)
|
||||
{
|
||||
var ip = Listen.Where(u => !u.Address.ToString().Equals("0.0.0.0", StringComparison.OrdinalIgnoreCase)).FirstOrDefault()
|
||||
?? new IPEndPoint(IPAddress.Parse("127.0.0.1"), defaultPort);
|
||||
ExternalUrl = new Uri($"http://{ip.Address}:{ip.Port}/");
|
||||
}
|
||||
|
||||
RequireHttps = config.GetOrDefault<bool>("requirehttps", false);
|
||||
Explorer = conf.GetOrDefault<Uri>("explorer.url", networkInfo.DefaultExplorerUrl);
|
||||
CookieFile = conf.GetOrDefault<string>("explorer.cookiefile", networkInfo.DefaultExplorerCookieFile);
|
||||
ExternalUrl = conf.GetOrDefault<Uri>("externalurl", null);
|
||||
RequireHttps = conf.GetOrDefault<bool>("requirehttps", false);
|
||||
}
|
||||
|
||||
public bool RequireHttps
|
||||
|
@ -121,92 +68,5 @@ namespace BTCPayServer.Configuration
|
|||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
private Uri GetDefaultNXplorerUri()
|
||||
{
|
||||
return new Uri("http://localhost:" + GetNXplorerDefaultPort(Network));
|
||||
}
|
||||
|
||||
|
||||
public string[] GetUrls()
|
||||
{
|
||||
return Listen.Select(b => "http://" + b + "/").ToArray();
|
||||
}
|
||||
|
||||
private void AssetConfigFileExists()
|
||||
{
|
||||
if(!File.Exists(ConfigurationFile))
|
||||
throw new ConfigurationException("Configuration file does not exists");
|
||||
}
|
||||
|
||||
public static IPEndPoint ConvertToEndpoint(string str, int defaultPort)
|
||||
{
|
||||
var portOut = defaultPort;
|
||||
var hostOut = "";
|
||||
int colon = str.LastIndexOf(':');
|
||||
// if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator
|
||||
bool fHaveColon = colon != -1;
|
||||
bool fBracketed = fHaveColon && (str[0] == '[' && str[colon - 1] == ']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe
|
||||
bool fMultiColon = fHaveColon && (str.LastIndexOf(':', colon - 1) != -1);
|
||||
if(fHaveColon && (colon == 0 || fBracketed || !fMultiColon))
|
||||
{
|
||||
int n;
|
||||
if(int.TryParse(str.Substring(colon + 1), out n) && n > 0 && n < 0x10000)
|
||||
{
|
||||
str = str.Substring(0, colon);
|
||||
portOut = n;
|
||||
}
|
||||
}
|
||||
if(str.Length > 0 && str[0] == '[' && str[str.Length - 1] == ']')
|
||||
hostOut = str.Substring(1, str.Length - 2);
|
||||
else
|
||||
hostOut = str;
|
||||
return new IPEndPoint(IPAddress.Parse(hostOut), portOut);
|
||||
}
|
||||
|
||||
const string DefaultConfigFile = "settings.config";
|
||||
private string GetDefaultConfigurationFile(bool createIfNotExist)
|
||||
{
|
||||
var config = Path.Combine(DataDir, DefaultConfigFile);
|
||||
Logs.Configuration.LogInformation("Configuration file set to " + config);
|
||||
if(createIfNotExist && !File.Exists(config))
|
||||
{
|
||||
Logs.Configuration.LogInformation("Creating configuration file");
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.AppendLine("### Global settings ###");
|
||||
builder.AppendLine("#testnet=0");
|
||||
builder.AppendLine("#regtest=0");
|
||||
builder.AppendLine("#Put here the xpub key of your hardware wallet");
|
||||
builder.AppendLine("#hdpubkey=xpub...");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("### Server settings ###");
|
||||
builder.AppendLine("#port=" + GetDefaultPort(Network));
|
||||
builder.AppendLine("#bind=127.0.0.1");
|
||||
builder.AppendLine("#externalurl=http://127.0.0.1/");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("### NBXplorer settings ###");
|
||||
builder.AppendLine("#explorer.url=" + GetDefaultNXplorerUri());
|
||||
builder.AppendLine("#explorer.cookiefile=" + GetExplorerDefaultCookiePath());
|
||||
File.WriteAllText(config, builder.ToString());
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
private string GetExplorerDefaultCookiePath()
|
||||
{
|
||||
return Path.Combine(DefaultDataDirectory.GetDefaultDirectory("NBXplorer", Network, false), ".cookie");
|
||||
}
|
||||
|
||||
private int GetNXplorerDefaultPort(Network network)
|
||||
{
|
||||
return network == Network.Main ? 24444 :
|
||||
network == Network.TestNet ? 24445 : 24446;
|
||||
}
|
||||
|
||||
private int GetDefaultPort(Network network)
|
||||
{
|
||||
return network == Network.Main ? 23000 :
|
||||
network == Network.TestNet ? 23001 : 23002;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace BTCPayServer.Configuration
|
|||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw new ConfigurationException($"Could not connect to NBXplorer, {ex.Message}");
|
||||
throw new ConfigException($"Could not connect to NBXplorer, {ex.Message}");
|
||||
}
|
||||
DBreezeEngine db = new DBreezeEngine(CreateDBPath(opts, "TokensDB"));
|
||||
_Resources.Add(db);
|
||||
|
|
15
BTCPayServer/Configuration/ConfigException.cs
Normal file
15
BTCPayServer/Configuration/ConfigException.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Configuration
|
||||
{
|
||||
public class ConfigException : Exception
|
||||
{
|
||||
public ConfigException(string message) : base(message)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
52
BTCPayServer/Configuration/ConfigurationExtensions.cs
Normal file
52
BTCPayServer/Configuration/ConfigurationExtensions.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace BTCPayServer.Configuration
|
||||
{
|
||||
public static class ConfigurationExtensions
|
||||
{
|
||||
public static T GetOrDefault<T>(this IConfiguration configuration, string key, T defaultValue)
|
||||
{
|
||||
var str = configuration[key] ?? configuration[key.Replace(".", string.Empty)];
|
||||
if(str == null)
|
||||
return defaultValue;
|
||||
if(typeof(T) == typeof(bool))
|
||||
{
|
||||
var trueValues = new[] { "1", "true" };
|
||||
var falseValues = new[] { "0", "false" };
|
||||
if(trueValues.Contains(str, StringComparer.OrdinalIgnoreCase))
|
||||
return (T)(object)true;
|
||||
if(falseValues.Contains(str, StringComparer.OrdinalIgnoreCase))
|
||||
return (T)(object)false;
|
||||
throw new FormatException();
|
||||
}
|
||||
else if(typeof(T) == typeof(Uri))
|
||||
return (T)(object)new Uri(str, UriKind.Absolute);
|
||||
else if(typeof(T) == typeof(string))
|
||||
return (T)(object)str;
|
||||
else if(typeof(T) == typeof(IPEndPoint))
|
||||
{
|
||||
var separator = str.LastIndexOf(":");
|
||||
if(separator == -1)
|
||||
throw new FormatException();
|
||||
var ip = str.Substring(0, separator);
|
||||
var port = str.Substring(separator + 1);
|
||||
return (T)(object)new IPEndPoint(IPAddress.Parse(ip), int.Parse(port));
|
||||
}
|
||||
else if(typeof(T) == typeof(int))
|
||||
{
|
||||
return (T)(object)int.Parse(str, CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("Configuration value does not support time " + typeof(T).Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
96
BTCPayServer/Configuration/DefaultConfiguration.cs
Normal file
96
BTCPayServer/Configuration/DefaultConfiguration.cs
Normal file
|
@ -0,0 +1,96 @@
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using NBitcoin;
|
||||
using System.Text;
|
||||
using CommandLine;
|
||||
|
||||
namespace BTCPayServer.Configuration
|
||||
{
|
||||
public class DefaultConfiguration : StandardConfiguration.DefaultConfiguration
|
||||
{
|
||||
protected override CommandLineApplication CreateCommandLineApplicationCore()
|
||||
{
|
||||
CommandLineApplication app = new CommandLineApplication(true)
|
||||
{
|
||||
FullName = "NBXplorer\r\nLightweight block explorer for tracking HD wallets",
|
||||
Name = "NBXplorer"
|
||||
};
|
||||
app.HelpOption("-? | -h | --help");
|
||||
app.Option("-n | --network", $"Set the network among ({NetworkInformation.ToStringAll()}) (default: {Network.Main.ToString()})", CommandOptionType.SingleValue);
|
||||
app.Option("--testnet | -testnet", $"Use testnet", CommandOptionType.BoolValue);
|
||||
app.Option("--regtest | -regtest", $"Use regtest", CommandOptionType.BoolValue);
|
||||
app.Option("--requirehttps", $"Will redirect to https version of the website (default: false)", CommandOptionType.BoolValue);
|
||||
app.Option("--externalurl", $"The external url of the website", CommandOptionType.SingleValue);
|
||||
app.Option("--explorerurl", $"Url of the NBxplorer (default: : Default setting of NBXplorer for the network)", CommandOptionType.SingleValue);
|
||||
app.Option("--explorercookiefile", $"Path to the cookie file (default: Default setting of NBXplorer for the network)", CommandOptionType.SingleValue);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
protected override string GetDefaultDataDir(IConfiguration conf)
|
||||
{
|
||||
return GetNetwork(conf).DefaultDataDirectory;
|
||||
}
|
||||
|
||||
protected override string GetDefaultConfigurationFile(IConfiguration conf)
|
||||
{
|
||||
var network = GetNetwork(conf);
|
||||
var dataDir = conf["datadir"];
|
||||
if(dataDir == null)
|
||||
return network.DefaultConfigurationFile;
|
||||
var fileName = Path.GetFileName(network.DefaultConfigurationFile);
|
||||
return Path.Combine(dataDir, fileName);
|
||||
}
|
||||
|
||||
public static NetworkInformation GetNetwork(IConfiguration conf)
|
||||
{
|
||||
var network = conf.GetOrDefault<string>("network", null);
|
||||
if(network != null)
|
||||
{
|
||||
var info = NetworkInformation.GetNetworkByName(network);
|
||||
if(info == null)
|
||||
throw new ConfigException($"Invalid network name {network}");
|
||||
return info;
|
||||
}
|
||||
|
||||
var net = conf.GetOrDefault<bool>("regtest", false) ? Network.RegTest :
|
||||
conf.GetOrDefault<bool>("testnet", false) ? Network.TestNet : Network.Main;
|
||||
|
||||
return NetworkInformation.GetNetworkByName(net.Name);
|
||||
}
|
||||
|
||||
protected override string GetDefaultConfigurationFileTemplate(IConfiguration conf)
|
||||
{
|
||||
var network = GetNetwork(conf);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.AppendLine("### Global settings ###");
|
||||
builder.AppendLine("#testnet=0");
|
||||
builder.AppendLine("#regtest=0");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("### Server settings ###");
|
||||
builder.AppendLine("#requirehttps=0");
|
||||
builder.AppendLine("#port=" + network.DefaultPort);
|
||||
builder.AppendLine("#bind=127.0.0.1");
|
||||
builder.AppendLine("#externalurl=http://127.0.0.1/");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("### NBXplorer settings ###");
|
||||
builder.AppendLine("#explorer.url=" + network.DefaultExplorerUrl.AbsoluteUri);
|
||||
builder.AppendLine("#explorer.cookiefile=" + network.DefaultExplorerCookieFile);
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override IPEndPoint GetDefaultEndpoint(IConfiguration conf)
|
||||
{
|
||||
return new IPEndPoint(IPAddress.Parse("127.0.0.1"), GetNetwork(conf).DefaultPort);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
using BTCPayServer.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NBitcoin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace BTCPayServer.Configuration
|
||||
{
|
||||
public class DefaultDataDirectory
|
||||
{
|
||||
public static string GetDefaultDirectory(string appName, Network network, bool createDirectory)
|
||||
{
|
||||
string directory = null;
|
||||
var home = Environment.GetEnvironmentVariable("HOME");
|
||||
if(!string.IsNullOrEmpty(home))
|
||||
{
|
||||
if(createDirectory)
|
||||
Logs.Configuration.LogInformation("Using HOME environment variable for initializing application data");
|
||||
directory = home;
|
||||
directory = Path.Combine(directory, "." + appName.ToLowerInvariant());
|
||||
}
|
||||
else
|
||||
{
|
||||
var localAppData = Environment.GetEnvironmentVariable("APPDATA");
|
||||
if(!string.IsNullOrEmpty(localAppData))
|
||||
{
|
||||
if(createDirectory)
|
||||
Logs.Configuration.LogInformation("Using APPDATA environment variable for initializing application data");
|
||||
directory = localAppData;
|
||||
directory = Path.Combine(directory, appName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DirectoryNotFoundException("Could not find suitable datadir");
|
||||
}
|
||||
}
|
||||
if(!Directory.Exists(directory) && createDirectory)
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
directory = Path.Combine(directory, network.Name);
|
||||
if(!Directory.Exists(directory) && createDirectory)
|
||||
{
|
||||
Logs.Configuration.LogInformation("Creating data directory");
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
return directory;
|
||||
}
|
||||
}
|
||||
}
|
103
BTCPayServer/Configuration/NetworkInformation.cs
Normal file
103
BTCPayServer/Configuration/NetworkInformation.cs
Normal file
|
@ -0,0 +1,103 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using NBitcoin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Configuration
|
||||
{
|
||||
public class NetworkInformation
|
||||
{
|
||||
static NetworkInformation()
|
||||
{
|
||||
_Networks = new Dictionary<string, NetworkInformation>();
|
||||
foreach(var network in Network.GetNetworks())
|
||||
{
|
||||
NetworkInformation info = new NetworkInformation();
|
||||
info.DefaultDataDirectory = StandardConfiguration.DefaultDataDirectory.GetDirectory("BTCPayServer", network.Name);
|
||||
info.DefaultConfigurationFile = Path.Combine(info.DefaultDataDirectory, "settings.config");
|
||||
info.DefaultExplorerCookieFile = Path.Combine(StandardConfiguration.DefaultDataDirectory.GetDirectory("NBXplorer", network.Name, false), ".cookie");
|
||||
info.Network = network;
|
||||
info.DefaultExplorerUrl = new Uri("http://127.0.0.1:24446", UriKind.Absolute);
|
||||
info.DefaultPort = 23002;
|
||||
_Networks.Add(network.Name, info);
|
||||
if(network == Network.Main)
|
||||
{
|
||||
info.DefaultExplorerUrl = new Uri("http://127.0.0.1:24444", UriKind.Absolute);
|
||||
Main = info;
|
||||
info.DefaultPort = 23000;
|
||||
}
|
||||
if(network == Network.TestNet)
|
||||
{
|
||||
info.DefaultExplorerUrl = new Uri("http://127.0.0.1:24445", UriKind.Absolute);
|
||||
info.DefaultPort = 23001;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Dictionary<string, NetworkInformation> _Networks;
|
||||
public static NetworkInformation GetNetworkByName(string name)
|
||||
{
|
||||
var value = _Networks.TryGet(name);
|
||||
if(value != null)
|
||||
return value;
|
||||
|
||||
//Maybe alias ?
|
||||
var network = Network.GetNetwork(name);
|
||||
if(network != null)
|
||||
{
|
||||
value = _Networks.TryGet(network.Name);
|
||||
if(value != null)
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static NetworkInformation Main
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public Network Network
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string DefaultConfigurationFile
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public string DefaultDataDirectory
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public Uri DefaultExplorerUrl
|
||||
{
|
||||
get;
|
||||
internal set;
|
||||
}
|
||||
public int DefaultPort
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string DefaultExplorerCookieFile
|
||||
{
|
||||
get;
|
||||
internal set;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Network.ToString();
|
||||
}
|
||||
|
||||
public static string ToStringAll()
|
||||
{
|
||||
return string.Join(", ", _Networks.Select(n => n.Key).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,221 +0,0 @@
|
|||
using NBitcoin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer
|
||||
{
|
||||
public class ConfigurationException : Exception
|
||||
{
|
||||
public ConfigurationException(string message) : base(message)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class TextFileConfiguration
|
||||
{
|
||||
private Dictionary<string, List<string>> _Args;
|
||||
|
||||
public TextFileConfiguration(string[] args)
|
||||
{
|
||||
_Args = new Dictionary<string, List<string>>();
|
||||
string noValueParam = null;
|
||||
Action flushNoValueParam = () =>
|
||||
{
|
||||
if(noValueParam != null)
|
||||
{
|
||||
Add(noValueParam, "1", false);
|
||||
noValueParam = null;
|
||||
}
|
||||
};
|
||||
|
||||
foreach(var arg in args)
|
||||
{
|
||||
bool isParamName = arg.StartsWith("-", StringComparison.Ordinal);
|
||||
if(isParamName)
|
||||
{
|
||||
var splitted = arg.Split('=');
|
||||
if(splitted.Length > 1)
|
||||
{
|
||||
var value = String.Join("=", splitted.Skip(1).ToArray());
|
||||
flushNoValueParam();
|
||||
Add(splitted[0], value, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
flushNoValueParam();
|
||||
noValueParam = splitted[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(noValueParam != null)
|
||||
{
|
||||
Add(noValueParam, arg, false);
|
||||
noValueParam = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
flushNoValueParam();
|
||||
}
|
||||
|
||||
private void Add(string key, string value, bool sourcePriority)
|
||||
{
|
||||
key = NormalizeKey(key);
|
||||
List<string> list;
|
||||
if(!_Args.TryGetValue(key, out list))
|
||||
{
|
||||
list = new List<string>();
|
||||
_Args.Add(key, list);
|
||||
}
|
||||
if(sourcePriority)
|
||||
list.Insert(0, value);
|
||||
else
|
||||
list.Add(value);
|
||||
}
|
||||
|
||||
private static string NormalizeKey(string key)
|
||||
{
|
||||
key = key.ToLowerInvariant();
|
||||
while(key.Length > 0 && key[0] == '-')
|
||||
{
|
||||
key = key.Substring(1);
|
||||
}
|
||||
key = key.Replace(".", "");
|
||||
return key;
|
||||
}
|
||||
|
||||
public void MergeInto(TextFileConfiguration destination, bool sourcePriority)
|
||||
{
|
||||
foreach(var kv in _Args)
|
||||
{
|
||||
foreach(var v in kv.Value)
|
||||
destination.Add(kv.Key, v, sourcePriority);
|
||||
}
|
||||
}
|
||||
|
||||
public TextFileConfiguration(Dictionary<string, List<string>> args)
|
||||
{
|
||||
_Args = args;
|
||||
}
|
||||
|
||||
public static TextFileConfiguration Parse(string data)
|
||||
{
|
||||
Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
|
||||
var lines = data.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
int lineCount = -1;
|
||||
foreach(var l in lines)
|
||||
{
|
||||
lineCount++;
|
||||
var line = l.Trim();
|
||||
if(line.StartsWith("#", StringComparison.Ordinal))
|
||||
continue;
|
||||
var split = line.Split('=');
|
||||
if(split.Length == 0)
|
||||
continue;
|
||||
if(split.Length == 1)
|
||||
throw new FormatException("Line " + lineCount + ": No value are set");
|
||||
|
||||
var key = split[0];
|
||||
key = NormalizeKey(key);
|
||||
List<string> values;
|
||||
if(!result.TryGetValue(key, out values))
|
||||
{
|
||||
values = new List<string>();
|
||||
result.Add(key, values);
|
||||
}
|
||||
var value = String.Join("=", split.Skip(1).ToArray());
|
||||
values.Add(value);
|
||||
}
|
||||
return new TextFileConfiguration(result);
|
||||
}
|
||||
|
||||
public bool Contains(string key)
|
||||
{
|
||||
List<string> values;
|
||||
return _Args.TryGetValue(key, out values);
|
||||
}
|
||||
public string[] GetAll(string key)
|
||||
{
|
||||
List<string> values;
|
||||
if(!_Args.TryGetValue(key, out values))
|
||||
return new string[0];
|
||||
return values.ToArray();
|
||||
}
|
||||
|
||||
private List<Tuple<string, string>> _Aliases = new List<Tuple<string, string>>();
|
||||
|
||||
public void AddAlias(string from, string to)
|
||||
{
|
||||
from = NormalizeKey(from);
|
||||
to = NormalizeKey(to);
|
||||
_Aliases.Add(Tuple.Create(from, to));
|
||||
}
|
||||
public T GetOrDefault<T>(string key, T defaultValue)
|
||||
{
|
||||
key = NormalizeKey(key);
|
||||
|
||||
var aliases = _Aliases
|
||||
.Where(a => a.Item1 == key || a.Item2 == key)
|
||||
.Select(a => a.Item1 == key ? a.Item2 : a.Item1)
|
||||
.ToList();
|
||||
aliases.Insert(0, key);
|
||||
|
||||
foreach(var alias in aliases)
|
||||
{
|
||||
List<string> values;
|
||||
if(!_Args.TryGetValue(alias, out values))
|
||||
continue;
|
||||
if(values.Count == 0)
|
||||
continue;
|
||||
try
|
||||
{
|
||||
return ConvertValue<T>(values[0]);
|
||||
}
|
||||
catch(FormatException) { throw new ConfigurationException("Key " + key + " should be of type " + typeof(T).Name); }
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private T ConvertValue<T>(string str)
|
||||
{
|
||||
if(typeof(T) == typeof(bool))
|
||||
{
|
||||
var trueValues = new[] { "1", "true" };
|
||||
var falseValues = new[] { "0", "false" };
|
||||
if(trueValues.Contains(str, StringComparer.OrdinalIgnoreCase))
|
||||
return (T)(object)true;
|
||||
if(falseValues.Contains(str, StringComparer.OrdinalIgnoreCase))
|
||||
return (T)(object)false;
|
||||
throw new FormatException();
|
||||
}
|
||||
else if(typeof(T) == typeof(Uri))
|
||||
return (T)(object)new Uri(str, UriKind.Absolute);
|
||||
else if(typeof(T) == typeof(string))
|
||||
return (T)(object)str;
|
||||
else if(typeof(T) == typeof(IPEndPoint))
|
||||
{
|
||||
var separator = str.LastIndexOf(":");
|
||||
if(separator == -1)
|
||||
throw new FormatException();
|
||||
var ip = str.Substring(0, separator);
|
||||
var port = str.Substring(separator + 1);
|
||||
return (T)(object)new IPEndPoint(IPAddress.Parse(ip), int.Parse(port));
|
||||
}
|
||||
else if(typeof(T) == typeof(int))
|
||||
{
|
||||
return (T)(object)int.Parse(str, CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("Configuration value does not support time " + typeof(T).Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
using BTCPayServer.Authentication;
|
||||
using BTCPayServer.Configuration;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
@ -8,6 +11,17 @@ namespace BTCPayServer
|
|||
{
|
||||
public static class Extensions
|
||||
{
|
||||
|
||||
public static IServiceCollection ConfigureBTCPayServer(this IServiceCollection services, IConfiguration conf)
|
||||
{
|
||||
services.Configure<BTCPayServerOptions>(o =>
|
||||
{
|
||||
o.LoadArgs(conf);
|
||||
});
|
||||
return services;
|
||||
}
|
||||
|
||||
|
||||
public static BitIdentity GetBitIdentity(this Controller controller)
|
||||
{
|
||||
if(!(controller.User.Identity is BitIdentity))
|
||||
|
|
|
@ -22,70 +22,142 @@ using BTCPayServer.Services.Stores;
|
|||
using BTCPayServer.Services.Fees;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Rewrite;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using BTCPayServer.Controllers;
|
||||
using BTCPayServer.Services.Mails;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using BTCPayServer.Models;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Hosting
|
||||
{
|
||||
public static class BTCPayServerServices
|
||||
{
|
||||
public static IWebHostBuilder AddPayServer(this IWebHostBuilder builder, BTCPayServerOptions options)
|
||||
public class OwnStoreAuthorizationRequirement : IAuthorizationRequirement
|
||||
{
|
||||
return
|
||||
builder
|
||||
.ConfigureServices(c =>
|
||||
public OwnStoreAuthorizationRequirement()
|
||||
{
|
||||
}
|
||||
|
||||
public OwnStoreAuthorizationRequirement(string role)
|
||||
{
|
||||
Role = role;
|
||||
}
|
||||
|
||||
public string Role
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
public class OwnStoreHandler : AuthorizationHandler<OwnStoreAuthorizationRequirement>
|
||||
{
|
||||
StoreRepository _StoreRepository;
|
||||
UserManager<ApplicationUser> _UserManager;
|
||||
public OwnStoreHandler(StoreRepository storeRepository, UserManager<ApplicationUser> userManager)
|
||||
{
|
||||
_StoreRepository = storeRepository;
|
||||
_UserManager = userManager;
|
||||
}
|
||||
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, OwnStoreAuthorizationRequirement requirement)
|
||||
{
|
||||
object storeId = null;
|
||||
if(!((Microsoft.AspNetCore.Mvc.ActionContext)context.Resource).RouteData.Values.TryGetValue("storeId", out storeId))
|
||||
context.Succeed(requirement);
|
||||
else
|
||||
{
|
||||
c.AddDbContext<ApplicationDbContext>(o =>
|
||||
{
|
||||
var path = Path.Combine(options.DataDir, "sqllite.db");
|
||||
o.UseSqlite("Data Source=" + path);
|
||||
});
|
||||
c.AddSingleton(options);
|
||||
c.AddSingleton<BTCPayServerRuntime>(o =>
|
||||
{
|
||||
var runtime = new BTCPayServerRuntime();
|
||||
runtime.Configure(options);
|
||||
return runtime;
|
||||
});
|
||||
var store = await _StoreRepository.FindStore((string)storeId, _UserManager.GetUserId(((Microsoft.AspNetCore.Mvc.ActionContext)context.Resource).HttpContext.User));
|
||||
if(store != null)
|
||||
if(requirement.Role == null || requirement.Role == store.Role)
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
}
|
||||
}
|
||||
class BTCPayServerConfigureOptions : IConfigureOptions<MvcOptions>
|
||||
{
|
||||
BTCPayServerOptions _Options;
|
||||
public BTCPayServerConfigureOptions(BTCPayServerOptions options)
|
||||
{
|
||||
_Options = options;
|
||||
}
|
||||
public void Configure(MvcOptions options)
|
||||
{
|
||||
if(_Options.RequireHttps)
|
||||
options.Filters.Add(new RequireHttpsAttribute());
|
||||
}
|
||||
}
|
||||
public static IServiceCollection AddBTCPayServer(this IServiceCollection services)
|
||||
{
|
||||
services.AddDbContext<ApplicationDbContext>((provider, o) =>
|
||||
{
|
||||
var path = Path.Combine(provider.GetRequiredService<BTCPayServerOptions>().DataDir, "sqllite.db");
|
||||
o.UseSqlite("Data Source=" + path);
|
||||
});
|
||||
services.TryAddSingleton<BTCPayServerOptions>(o => o.GetRequiredService<IOptions<BTCPayServerOptions>>().Value);
|
||||
services.TryAddSingleton<IConfigureOptions<MvcOptions>, BTCPayServerConfigureOptions>();
|
||||
services.TryAddSingleton(o =>
|
||||
{
|
||||
var runtime = new BTCPayServerRuntime();
|
||||
runtime.Configure(o.GetRequiredService<BTCPayServerOptions>());
|
||||
return runtime;
|
||||
});
|
||||
services.TryAddSingleton(o => o.GetRequiredService<BTCPayServerRuntime>().TokenRepository);
|
||||
services.TryAddSingleton(o => o.GetRequiredService<BTCPayServerRuntime>().InvoiceRepository);
|
||||
services.TryAddSingleton<Network>(o => o.GetRequiredService<BTCPayServerOptions>().Network);
|
||||
services.TryAddSingleton<ApplicationDbContextFactory>(o => o.GetRequiredService<BTCPayServerRuntime>().DBFactory);
|
||||
services.TryAddSingleton<StoreRepository>();
|
||||
services.TryAddSingleton(o => o.GetRequiredService<BTCPayServerRuntime>().Wallet);
|
||||
services.TryAddSingleton<CurrencyNameTable>();
|
||||
services.TryAddSingleton<IFeeProvider>(o => new NBXplorerFeeProvider()
|
||||
{
|
||||
Fallback = new FeeRate(100, 1),
|
||||
BlockTarget = 20,
|
||||
ExplorerClient = o.GetRequiredService<ExplorerClient>()
|
||||
});
|
||||
services.TryAddSingleton<ExplorerClient>(o =>
|
||||
{
|
||||
var runtime = o.GetRequiredService<BTCPayServerRuntime>();
|
||||
return runtime.Explorer;
|
||||
});
|
||||
services.TryAddSingleton<Bitpay>(o =>
|
||||
{
|
||||
if(o.GetRequiredService<BTCPayServerOptions>().Network == Network.Main)
|
||||
return new Bitpay(new Key(), new Uri("https://bitpay.com/"));
|
||||
else
|
||||
return new Bitpay(new Key(), new Uri("https://test.bitpay.com/"));
|
||||
});
|
||||
services.TryAddSingleton<IRateProvider, BitpayRateProvider>();
|
||||
services.TryAddSingleton<InvoiceWatcher>();
|
||||
services.TryAddSingleton<IHostedService>(o => o.GetRequiredService<InvoiceWatcher>());
|
||||
services.TryAddScoped<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.TryAddSingleton<IExternalUrlProvider>(o =>
|
||||
{
|
||||
var op = o.GetRequiredService<BTCPayServerOptions>();
|
||||
if(op.ExternalUrl != null)
|
||||
return new FixedExternalUrlProvider(op.ExternalUrl, o.GetRequiredService<IHttpContextAccessor>());
|
||||
return new DefaultExternalUrlProvider(o.GetRequiredService<IHttpContextAccessor>());
|
||||
});
|
||||
services.TryAddSingleton<IAuthorizationHandler, OwnStoreHandler>();
|
||||
services.AddTransient<AccessTokenController>();
|
||||
// Add application services.
|
||||
services.AddTransient<IEmailSender, EmailSender>();
|
||||
|
||||
if(options.RequireHttps)
|
||||
{
|
||||
c.Configure<MvcOptions>(o =>
|
||||
{
|
||||
o.Filters.Add(new RequireHttpsAttribute());
|
||||
});
|
||||
}
|
||||
services.AddAuthorization(o =>
|
||||
{
|
||||
o.AddPolicy("CanAccessStore", builder =>
|
||||
{
|
||||
builder.AddRequirements(new OwnStoreAuthorizationRequirement());
|
||||
});
|
||||
|
||||
c.AddSingleton<Network>(options.Network);
|
||||
c.AddSingleton(o => o.GetRequiredService<BTCPayServerRuntime>().TokenRepository);
|
||||
c.AddSingleton(o => o.GetRequiredService<BTCPayServerRuntime>().InvoiceRepository);
|
||||
c.AddSingleton<ApplicationDbContextFactory>(o => o.GetRequiredService<BTCPayServerRuntime>().DBFactory);
|
||||
c.AddSingleton<StoreRepository>();
|
||||
c.AddSingleton(o => o.GetRequiredService<BTCPayServerRuntime>().Wallet);
|
||||
c.AddSingleton<CurrencyNameTable>();
|
||||
c.AddSingleton<IFeeProvider>(o => new NBXplorerFeeProvider()
|
||||
{
|
||||
Fallback = new FeeRate(100, 1),
|
||||
BlockTarget = 20,
|
||||
ExplorerClient = o.GetRequiredService<ExplorerClient>()
|
||||
});
|
||||
c.AddSingleton<ExplorerClient>(o =>
|
||||
{
|
||||
var runtime = o.GetRequiredService<BTCPayServerRuntime>();
|
||||
return runtime.Explorer;
|
||||
});
|
||||
c.AddSingleton<Bitpay>(o =>
|
||||
{
|
||||
if(options.Network == Network.Main)
|
||||
return new Bitpay(new Key(), new Uri("https://bitpay.com/"));
|
||||
else
|
||||
return new Bitpay(new Key(), new Uri("https://test.bitpay.com/"));
|
||||
});
|
||||
c.TryAddSingleton<IRateProvider, BitpayRateProvider>();
|
||||
c.AddSingleton<InvoiceWatcher>();
|
||||
c.AddSingleton<IHostedService>(o => o.GetRequiredService<InvoiceWatcher>());
|
||||
c.AddScoped<IHttpContextAccessor, HttpContextAccessor>();
|
||||
c.AddSingleton<IExternalUrlProvider>(o => new FixedExternalUrlProvider(options.ExternalUrl, o.GetRequiredService<IHttpContextAccessor>()));
|
||||
})
|
||||
.UseUrls(options.GetUrls());
|
||||
o.AddPolicy("OwnStore", builder =>
|
||||
{
|
||||
builder.AddRequirements(new OwnStoreAuthorizationRequirement("Owner"));
|
||||
});
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UsePayServer(this IApplicationBuilder app)
|
||||
|
|
|
@ -23,45 +23,30 @@ using System.Threading.Tasks;
|
|||
using BTCPayServer.Controllers;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using BTCPayServer.Services.Mails;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace BTCPayServer.Hosting
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration conf)
|
||||
{
|
||||
Configuration = conf;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.ConfigureBTCPayServer(Configuration);
|
||||
|
||||
services.AddIdentity<ApplicationUser, IdentityRole>()
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
services.AddAuthorization(o =>
|
||||
{
|
||||
o.AddPolicy("CanAccessStore", builder =>
|
||||
{
|
||||
builder.AddRequirements(new OwnStoreAuthorizationRequirement());
|
||||
});
|
||||
|
||||
o.AddPolicy("OwnStore", builder =>
|
||||
{
|
||||
builder.AddRequirements(new OwnStoreAuthorizationRequirement("Owner"));
|
||||
});
|
||||
});
|
||||
services.AddSingleton<IAuthorizationHandler, OwnStoreHandler>();
|
||||
services.AddTransient<AccessTokenController>();
|
||||
// Add application services.
|
||||
services.AddTransient<IEmailSender, EmailSender>();
|
||||
|
||||
//services.AddSingleton<IObjectModelValidator, NoObjectModelValidator>();
|
||||
services.AddMvcCore(o =>
|
||||
{
|
||||
//o.Filters.Add(new NBXplorerExceptionFilter());
|
||||
o.OutputFormatters.Clear();
|
||||
o.InputFormatters.Clear();
|
||||
})
|
||||
.AddJsonFormatters()
|
||||
.AddFormatterMappings();
|
||||
|
||||
services.AddBTCPayServer();
|
||||
services.AddMvc();
|
||||
}
|
||||
public void Configure(
|
||||
|
@ -74,6 +59,8 @@ namespace BTCPayServer.Hosting
|
|||
app.UseDeveloperExceptionPage();
|
||||
app.UseBrowserLink();
|
||||
}
|
||||
|
||||
|
||||
Logs.Configure(loggerFactory);
|
||||
app.UsePayServer();
|
||||
app.UseStaticFiles();
|
||||
|
@ -87,45 +74,4 @@ namespace BTCPayServer.Hosting
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class OwnStoreAuthorizationRequirement : IAuthorizationRequirement
|
||||
{
|
||||
public OwnStoreAuthorizationRequirement()
|
||||
{
|
||||
}
|
||||
|
||||
public OwnStoreAuthorizationRequirement(string role)
|
||||
{
|
||||
Role = role;
|
||||
}
|
||||
|
||||
public string Role
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
public class OwnStoreHandler : AuthorizationHandler<OwnStoreAuthorizationRequirement>
|
||||
{
|
||||
StoreRepository _StoreRepository;
|
||||
UserManager<ApplicationUser> _UserManager;
|
||||
public OwnStoreHandler(StoreRepository storeRepository, UserManager<ApplicationUser> userManager)
|
||||
{
|
||||
_StoreRepository = storeRepository;
|
||||
_UserManager = userManager;
|
||||
}
|
||||
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, OwnStoreAuthorizationRequirement requirement)
|
||||
{
|
||||
object storeId = null;
|
||||
if(!((Microsoft.AspNetCore.Mvc.ActionContext)context.Resource).RouteData.Values.TryGetValue("storeId", out storeId))
|
||||
context.Succeed(requirement);
|
||||
else
|
||||
{
|
||||
var store = await _StoreRepository.FindStore((string)storeId, _UserManager.GetUserId(((Microsoft.AspNetCore.Mvc.ActionContext)context.Resource).HttpContext.User));
|
||||
if(store != null)
|
||||
if(requirement.Role == null || requirement.Role == store.Role)
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ using System.IO;
|
|||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using System.Threading;
|
||||
|
||||
namespace BTCPayServer
|
||||
{
|
||||
|
@ -22,18 +24,22 @@ namespace BTCPayServer
|
|||
{
|
||||
ServicePointManager.DefaultConnectionLimit = 100;
|
||||
IWebHost host = null;
|
||||
CustomConsoleLogProvider loggerProvider = new CustomConsoleLogProvider();
|
||||
|
||||
var loggerFactory = new LoggerFactory();
|
||||
loggerFactory.AddProvider(loggerProvider);
|
||||
var logger = loggerFactory.CreateLogger("Configuration");
|
||||
try
|
||||
{
|
||||
var conf = new BTCPayServerOptions();
|
||||
var arguments = new TextFileConfiguration(args);
|
||||
arguments = LoadEnvironmentVariables(arguments);
|
||||
conf.LoadArgs(arguments);
|
||||
var conf = new DefaultConfiguration() { Logger = logger }.CreateConfiguration(args);
|
||||
if(conf == null)
|
||||
return;
|
||||
|
||||
host = new WebHostBuilder()
|
||||
.AddPayServer(conf)
|
||||
.UseKestrel()
|
||||
.UseIISIntegration()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseConfiguration(conf)
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddLogging(l =>
|
||||
|
@ -44,11 +50,19 @@ namespace BTCPayServer
|
|||
})
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
var running = host.RunAsync();
|
||||
OpenBrowser(conf.GetUrls().Select(url => url.Replace("0.0.0.0", "127.0.0.1")).First());
|
||||
running.GetAwaiter().GetResult();
|
||||
}
|
||||
catch(ConfigurationException ex)
|
||||
host.StartAsync().GetAwaiter().GetResult();
|
||||
var urls = host.ServerFeatures.Get<IServerAddressesFeature>().Addresses;
|
||||
if(urls.Count != 0)
|
||||
{
|
||||
OpenBrowser(urls.Select(url => url.Replace("0.0.0.0", "127.0.0.1")).First());
|
||||
}
|
||||
foreach(var url in urls)
|
||||
{
|
||||
logger.LogInformation("Listening on " + url);
|
||||
}
|
||||
host.WaitForShutdown();
|
||||
}
|
||||
catch(ConfigException ex)
|
||||
{
|
||||
if(!string.IsNullOrEmpty(ex.Message))
|
||||
Logs.Configuration.LogError(ex.Message);
|
||||
|
@ -62,30 +76,10 @@ namespace BTCPayServer
|
|||
{
|
||||
if(host != null)
|
||||
host.Dispose();
|
||||
loggerProvider.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static TextFileConfiguration LoadEnvironmentVariables(TextFileConfiguration args)
|
||||
{
|
||||
var variables = Environment.GetEnvironmentVariables();
|
||||
List<string> values = new List<string>();
|
||||
foreach(DictionaryEntry variable in variables)
|
||||
{
|
||||
var key = (string)variable.Key;
|
||||
var value = (string)variable.Value;
|
||||
if(key.StartsWith("APPSETTING_", StringComparison.Ordinal))
|
||||
{
|
||||
key = key.Substring("APPSETTING_".Length);
|
||||
values.Add("-" + key);
|
||||
values.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
TextFileConfiguration envConfig = new TextFileConfiguration(values.ToArray());
|
||||
args.MergeInto(envConfig, true);
|
||||
return envConfig;
|
||||
}
|
||||
|
||||
public static void OpenBrowser(string url)
|
||||
{
|
||||
try
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 1.4 KiB |
Loading…
Add table
Reference in a new issue