Add experimental mode

This commit is contained in:
nicolas.dorier 2022-05-23 10:46:51 +09:00
parent c7d0537bf9
commit 3285f24fe9
No known key found for this signature in database
GPG key ID: 6618763EF09186FE
10 changed files with 60 additions and 16 deletions

View file

@ -137,6 +137,8 @@ namespace BTCPayServer.Tests
} }
if (CheatMode) if (CheatMode)
config.AppendLine("cheatmode=1"); config.AppendLine("cheatmode=1");
if (Experimental)
config.AppendLine("experimental=1");
config.AppendLine($"torrcfile={TestUtils.GetTestDataFullPath("Tor/torrc")}"); config.AppendLine($"torrcfile={TestUtils.GetTestDataFullPath("Tor/torrc")}");
config.AppendLine($"socksendpoint={SocksEndpoint}"); config.AppendLine($"socksendpoint={SocksEndpoint}");
@ -291,6 +293,7 @@ namespace BTCPayServer.Tests
public string SSHKeyFile { get; internal set; } public string SSHKeyFile { get; internal set; }
public string SSHConnection { get; set; } public string SSHConnection { get; set; }
public bool NoCSP { 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 public T GetController<T>(string userId = null, string storeId = null, bool isAdmin = false) where T : Controller
{ {

View file

@ -2519,6 +2519,7 @@ namespace BTCPayServer.Tests
public async Task CustodiansControllerTests() public async Task CustodiansControllerTests()
{ {
using var tester = CreateServerTester(); using var tester = CreateServerTester();
tester.PayTester.Experimental = true;
await tester.StartAsync(); await tester.StartAsync();
var unauthClient = new BTCPayServerClient(tester.PayTester.ServerUri); var unauthClient = new BTCPayServerClient(tester.PayTester.ServerUri);
await AssertHttpError(401, async () => await unauthClient.GetCustodians()); await AssertHttpError(401, async () => await unauthClient.GetCustodians());
@ -2538,6 +2539,7 @@ namespace BTCPayServer.Tests
{ {
using var tester = CreateServerTester(); using var tester = CreateServerTester();
tester.PayTester.Experimental = true;
await tester.StartAsync(); await tester.StartAsync();
var admin = tester.NewAccount(); var admin = tester.NewAccount();
@ -2709,6 +2711,7 @@ namespace BTCPayServer.Tests
public async Task CustodianTests() public async Task CustodianTests()
{ {
using var tester = CreateServerTester(); using var tester = CreateServerTester();
tester.PayTester.Experimental = true;
await tester.StartAsync(); await tester.StartAsync();
var admin = tester.NewAccount(); var admin = tester.NewAccount();

View file

@ -147,6 +147,7 @@ namespace BTCPayServer.Configuration
PluginRemote = conf.GetOrDefault("plugin-remote", "btcpayserver/btcpayserver-plugins"); 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(); RecommendedPlugins = conf.GetOrDefault("recommended-plugins", "").ToLowerInvariant().Split('\r', '\n', '\t', ' ').Where(s => !string.IsNullOrEmpty(s)).Distinct().ToArray();
CheatMode = conf.GetOrDefault("cheatmode", false); CheatMode = conf.GetOrDefault("cheatmode", false);
Experimental = conf.GetOrDefault("experimental", false);
if (CheatMode && this.NetworkType == ChainName.Mainnet) if (CheatMode && this.NetworkType == ChainName.Mainnet)
throw new ConfigException($"cheatmode can't be used on mainnet"); throw new ConfigException($"cheatmode can't be used on mainnet");
} }
@ -154,6 +155,7 @@ namespace BTCPayServer.Configuration
public string PluginRemote { get; set; } public string PluginRemote { get; set; }
public string[] RecommendedPlugins { get; set; } public string[] RecommendedPlugins { get; set; }
public bool CheatMode { get; set; } public bool CheatMode { get; set; }
public bool Experimental { get; set; }
private SSHSettings ParseSSHConfiguration(IConfiguration conf) private SSHSettings ParseSSHConfiguration(IConfiguration conf)
{ {

View file

@ -49,7 +49,8 @@ namespace BTCPayServer.Configuration
app.Option("--plugin-remote", "Which github repository to fetch the available plugins list (default:btcpayserver/btcpayserver-plugins)", CommandOptionType.SingleValue); app.Option("--plugin-remote", "Which github repository to fetch the available plugins list (default:btcpayserver/btcpayserver-plugins)", CommandOptionType.SingleValue);
app.Option("--recommended-plugins", "Plugins which would be marked as recommended to be installed. Separated by newline or space", CommandOptionType.MultipleValue); 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("--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 elements in the UI to facilitate dev-time testing (Default false)", CommandOptionType.BoolValue); 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); 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>()) foreach (var network in provider.GetAll().OfType<BTCPayNetwork>())

View file

@ -10,6 +10,7 @@ using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Client; using BTCPayServer.Client;
using BTCPayServer.Client.Models; using BTCPayServer.Client.Models;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Filters;
using BTCPayServer.Security; using BTCPayServer.Security;
using BTCPayServer.Services.Custodian; using BTCPayServer.Services.Custodian;
using BTCPayServer.Services.Custodian.Client; using BTCPayServer.Services.Custodian.Client;
@ -38,6 +39,7 @@ namespace BTCPayServer.Controllers.Greenfield
[Authorize(AuthenticationSchemes = AuthenticationSchemes.GreenfieldAPIKeys)] [Authorize(AuthenticationSchemes = AuthenticationSchemes.GreenfieldAPIKeys)]
[EnableCors(CorsPolicies.All)] [EnableCors(CorsPolicies.All)]
[CustodianExceptionFilter] [CustodianExceptionFilter]
[ExperimentalRouteAttribute] // if you remove this, also remove "x_experimental": true in swagger.template.custodians.json
public class GreenfieldCustodianAccountController : ControllerBase public class GreenfieldCustodianAccountController : ControllerBase
{ {
private readonly CustodianAccountRepository _custodianAccountRepository; private readonly CustodianAccountRepository _custodianAccountRepository;

View file

@ -3,6 +3,7 @@ using System.Linq;
using BTCPayServer.Abstractions.Constants; using BTCPayServer.Abstractions.Constants;
using BTCPayServer.Abstractions.Custodians; using BTCPayServer.Abstractions.Custodians;
using BTCPayServer.Client.Models; using BTCPayServer.Client.Models;
using BTCPayServer.Filters;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -12,6 +13,7 @@ namespace BTCPayServer.Controllers.Greenfield
[ApiController] [ApiController]
[Authorize(AuthenticationSchemes = AuthenticationSchemes.GreenfieldAPIKeys)] [Authorize(AuthenticationSchemes = AuthenticationSchemes.GreenfieldAPIKeys)]
[EnableCors(CorsPolicies.All)] [EnableCors(CorsPolicies.All)]
[ExperimentalRouteAttribute] // if you remove this, also remove "x_experimental": true in swagger.template.custodians.json
public class GreenfieldCustodianController : ControllerBase public class GreenfieldCustodianController : ControllerBase
{ {
private readonly IEnumerable<ICustodian> _custodianRegistry; private readonly IEnumerable<ICustodian> _custodianRegistry;

View file

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Services;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.Extensions.DependencyInjection;
namespace BTCPayServer.Filters
{
public class ExperimentalRouteAttribute : Attribute, IActionConstraint
{
public int Order => 100;
public bool Accept(ActionConstraintContext context)
{
return context.RouteContext.HttpContext.RequestServices.GetRequiredService<BTCPayServerEnvironment>().Experimental;
}
}
}

View file

@ -35,6 +35,7 @@ namespace BTCPayServer.Services
NetworkType = provider.NetworkType; NetworkType = provider.NetworkType;
this.torServices = torServices; this.torServices = torServices;
CheatMode = opts.CheatMode; CheatMode = opts.CheatMode;
Experimental = opts.Experimental;
} }
public IWebHostEnvironment Environment public IWebHostEnvironment Environment
{ {
@ -80,6 +81,8 @@ namespace BTCPayServer.Services
public HttpContext Context => httpContext.HttpContext; public HttpContext Context => httpContext.HttpContext;
public bool Experimental { get; set; }
public override string ToString() public override string ToString()
{ {
StringBuilder txt = new StringBuilder(); StringBuilder txt = new StringBuilder();

View file

@ -1,4 +1,4 @@
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Abstractions.Contracts; using BTCPayServer.Abstractions.Contracts;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
@ -11,11 +11,15 @@ public class DefaultSwaggerProvider: ISwaggerProvider
{ {
private readonly IFileProvider _fileProvider; private readonly IFileProvider _fileProvider;
public DefaultSwaggerProvider(IWebHostEnvironment webHostEnvironment) public DefaultSwaggerProvider(IWebHostEnvironment webHostEnvironment, BTCPayServerEnvironment env)
{ {
_fileProvider = webHostEnvironment.WebRootFileProvider; _fileProvider = webHostEnvironment.WebRootFileProvider;
Env = env;
} }
public BTCPayServerEnvironment Env { get; }
public async Task<JObject> Fetch() public async Task<JObject> Fetch()
{ {
@ -25,7 +29,10 @@ public class DefaultSwaggerProvider: ISwaggerProvider
{ {
await using var stream = fi.CreateReadStream(); await using var stream = fi.CreateReadStream();
using var reader = new StreamReader(fi.CreateReadStream()); using var reader = new StreamReader(fi.CreateReadStream());
json.Merge(JObject.Parse(await reader.ReadToEndAsync())); var jObject = JObject.Parse(await reader.ReadToEndAsync());
if (jObject.Remove("x_experimental") && !Env.Experimental)
continue;
json.Merge(jObject);
} }
return json; return json;

View file

@ -1,9 +1,10 @@
{ {
"x_experimental": true,
"paths": { "paths": {
"/api/v1/custodians": { "/api/v1/custodians": {
"get": { "get": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "List supported custodians", "summary": "List supported custodians",
"description": "List all supported custodians for the BTCPay instance. You can install plugins to add more custodians.", "description": "List all supported custodians for the BTCPay instance. You can install plugins to add more custodians.",
@ -34,7 +35,7 @@
"/api/v1/stores/{storeId}/custodian-accounts": { "/api/v1/stores/{storeId}/custodian-accounts": {
"get": { "get": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "List store custodian accounts", "summary": "List store custodian accounts",
"parameters": [ "parameters": [
@ -79,7 +80,7 @@
}, },
"post": { "post": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "Add a custodial account to a store.", "summary": "Add a custodial account to a store.",
"description": "Add a custodial account to a store.", "description": "Add a custodial account to a store.",
@ -123,7 +124,7 @@
"/api/v1/stores/{storeId}/custodian-accounts/{accountId}": { "/api/v1/stores/{storeId}/custodian-accounts/{accountId}": {
"get": { "get": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "Get store custodian account", "summary": "Get store custodian account",
"parameters": [ "parameters": [
@ -174,7 +175,7 @@
}, },
"put": { "put": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "Update custodial account", "summary": "Update custodial account",
"description": "Update custodial account", "description": "Update custodial account",
@ -216,7 +217,7 @@
}, },
"delete": { "delete": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "Delete store custodian account", "summary": "Delete store custodian account",
"description": "Deletes a custodial account", "description": "Deletes a custodial account",
@ -233,7 +234,7 @@
"/api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/quote": { "/api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/quote": {
"get": { "get": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "Get quote for trading one asset for another", "summary": "Get quote for trading one asset for another",
"description": "Get the current bid and ask price for converting one asset into another.", "description": "Get the current bid and ask price for converting one asset into another.",
@ -306,7 +307,7 @@
"/api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/market": { "/api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/market": {
"post": { "post": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "Trade one asset for another", "summary": "Trade one asset for another",
"description": "Trade one asset for another using a market order (=instant purchase with instant result or failure). A suitable asset pair will automatically be selected. If no asset pair is available, the call will fail.", "description": "Trade one asset for another using a market order (=instant purchase with instant result or failure). A suitable asset pair will automatically be selected. If no asset pair is available, the call will fail.",
@ -371,7 +372,7 @@
"/api/v1/stores/{storeId}/custodian-accounts/{accountId}/addresses/{paymentMethod}": { "/api/v1/stores/{storeId}/custodian-accounts/{accountId}/addresses/{paymentMethod}": {
"get": { "get": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "Get a deposit address for custodian", "summary": "Get a deposit address for custodian",
"description": "Get a new deposit address for the custodian using the specified payment method (network + crypto code).", "description": "Get a new deposit address for the custodian using the specified payment method (network + crypto code).",
@ -445,7 +446,7 @@
"/api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals": { "/api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals": {
"post": { "post": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "Withdraw to store wallet", "summary": "Withdraw to store wallet",
"description": "Withdraw an asset to your store wallet.", "description": "Withdraw an asset to your store wallet.",
@ -531,7 +532,7 @@
"/api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals/{withdrawalId}": { "/api/v1/stores/{storeId}/custodian-accounts/{accountId}/withdrawals/{withdrawalId}": {
"post": { "post": {
"tags": [ "tags": [
"Custodians (Experimental)" "Custodians"
], ],
"summary": "Get withdrawal info", "summary": "Get withdrawal info",
"description": "Get the details about a past withdrawal.", "description": "Get the details about a past withdrawal.",
@ -1034,7 +1035,7 @@
}, },
"tags": [ "tags": [
{ {
"name": "Custodians (Experimental)" "name": "Custodians"
} }
] ]
} }