Plugins: Recommended plugins and github Remote config options (#2045)

This allows external integrations ( btcpay docker fragments) to highlight specific plugins as recommended to be installed. Also moved the remote option to  a config option instead of a url query param to avoid messy situations where users could get deceived with a generated url. The dockerfiles also have an additional csproj to build and the plugin dir was renamed correctly from extensions to plugins
This commit is contained in:
Andrew Camilleri
2020-11-05 10:21:09 +01:00
committed by GitHub
parent 493b10393b
commit 38fb64130d
9 changed files with 35 additions and 17 deletions

View File

@@ -25,7 +25,7 @@ namespace BTCPayServer
_Settings.Add(chainType, settings); _Settings.Add(chainType, settings);
settings.DefaultDataDirectory = StandardConfiguration.DefaultDataDirectory.GetDirectory("BTCPayServer", NBXplorerDefaultSettings.GetFolderName(chainType)); settings.DefaultDataDirectory = StandardConfiguration.DefaultDataDirectory.GetDirectory("BTCPayServer", NBXplorerDefaultSettings.GetFolderName(chainType));
settings.DefaultPluginDirectory = settings.DefaultPluginDirectory =
StandardConfiguration.DefaultDataDirectory.GetDirectory("BTCPayServer", "Extensions"); StandardConfiguration.DefaultDataDirectory.GetDirectory("BTCPayServer", "Plugins");
settings.DefaultConfigurationFile = Path.Combine(settings.DefaultDataDirectory, "settings.config"); settings.DefaultConfigurationFile = Path.Combine(settings.DefaultDataDirectory, "settings.config");
settings.DefaultPort = (chainType == NetworkType.Mainnet ? 23000 : settings.DefaultPort = (chainType == NetworkType.Mainnet ? 23000 :
chainType == NetworkType.Regtest ? 23002 : chainType == NetworkType.Regtest ? 23002 :

View File

@@ -241,9 +241,13 @@ namespace BTCPayServer.Configuration
} }
DisableRegistration = conf.GetOrDefault<bool>("disable-registration", true); DisableRegistration = conf.GetOrDefault<bool>("disable-registration", true);
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();
} }
public string PluginDir { get; set; } public string PluginDir { get; set; }
public string PluginRemote { get; set; }
public string[] RecommendedPlugins { get; set; }
private SSHSettings ParseSSHConfiguration(IConfiguration conf) private SSHSettings ParseSSHConfiguration(IConfiguration conf)
{ {

View File

@@ -43,6 +43,8 @@ namespace BTCPayServer.Configuration
app.Option("--debuglog", "A rolling log file for debug messages.", CommandOptionType.SingleValue); app.Option("--debuglog", "A rolling log file for debug messages.", CommandOptionType.SingleValue);
app.Option("--debugloglevel", "The severity you log (default:information)", CommandOptionType.SingleValue); app.Option("--debugloglevel", "The severity you log (default:information)", CommandOptionType.SingleValue);
app.Option("--disable-registration", "Disables new user registrations (default:true)", CommandOptionType.SingleValue); app.Option("--disable-registration", "Disables new user registrations (default:true)", 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("--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);
foreach (var network in provider.GetAll().OfType<BTCPayNetwork>()) foreach (var network in provider.GetAll().OfType<BTCPayNetwork>())
{ {

View File

@@ -16,13 +16,12 @@ namespace BTCPayServer.Controllers
[HttpGet("server/plugins")] [HttpGet("server/plugins")]
public async Task<IActionResult> ListPlugins( public async Task<IActionResult> ListPlugins(
[FromServices] PluginService pluginService, [FromServices] PluginService pluginService,
[FromServices] BTCPayServerOptions btcPayServerOptions, [FromServices] BTCPayServerOptions btcPayServerOptions)
string remote = "btcpayserver/btcpayserver-plugins")
{ {
IEnumerable<PluginService.AvailablePlugin> availablePlugins; IEnumerable<PluginService.AvailablePlugin> availablePlugins;
try try
{ {
availablePlugins = await pluginService.GetRemotePlugins(remote); availablePlugins = await pluginService.GetRemotePlugins();
} }
catch (Exception) catch (Exception)
{ {
@@ -37,7 +36,6 @@ namespace BTCPayServer.Controllers
{ {
Installed = pluginService.LoadedPlugins, Installed = pluginService.LoadedPlugins,
Available = availablePlugins, Available = availablePlugins,
Remote = remote,
Commands = pluginService.GetPendingCommands(), Commands = pluginService.GetPendingCommands(),
CanShowRestart = btcPayServerOptions.DockerDeployment CanShowRestart = btcPayServerOptions.DockerDeployment
}; };
@@ -46,7 +44,6 @@ namespace BTCPayServer.Controllers
public class ListPluginsViewModel public class ListPluginsViewModel
{ {
public string Remote { get; set; }
public IEnumerable<IBTCPayServerPlugin> Installed { get; set; } public IEnumerable<IBTCPayServerPlugin> Installed { get; set; }
public IEnumerable<PluginService.AvailablePlugin> Available { get; set; } public IEnumerable<PluginService.AvailablePlugin> Available { get; set; }
public (string command, string plugin)[] Commands { get; set; } public (string command, string plugin)[] Commands { get; set; }
@@ -82,11 +79,11 @@ namespace BTCPayServer.Controllers
[HttpPost("server/plugins/install")] [HttpPost("server/plugins/install")]
public async Task<IActionResult> InstallPlugin( public async Task<IActionResult> InstallPlugin(
[FromServices] PluginService pluginService, string remote, string plugin) [FromServices] PluginService pluginService, string plugin)
{ {
try try
{ {
await pluginService.DownloadRemotePlugin(remote, plugin); await pluginService.DownloadRemotePlugin(plugin);
pluginService.InstallPlugin(plugin); pluginService.InstallPlugin(plugin);
TempData.SetStatusMessageModel(new StatusMessageModel() TempData.SetStatusMessageModel(new StatusMessageModel()
{ {

View File

@@ -31,10 +31,10 @@ namespace BTCPayServer.Plugins
public IEnumerable<IBTCPayServerPlugin> LoadedPlugins { get; } public IEnumerable<IBTCPayServerPlugin> LoadedPlugins { get; }
public async Task<IEnumerable<AvailablePlugin>> GetRemotePlugins(string remote) public async Task<IEnumerable<AvailablePlugin>> GetRemotePlugins()
{ {
var resp = await _githubClient var resp = await _githubClient
.GetStringAsync(new Uri($"https://api.github.com/repos/{remote}/contents")); .GetStringAsync(new Uri($"https://api.github.com/repos/{_btcPayServerOptions.PluginRemote}/contents"));
var files = JsonConvert.DeserializeObject<GithubFile[]>(resp); var files = JsonConvert.DeserializeObject<GithubFile[]>(resp);
return await Task.WhenAll(files.Where(file => file.Name.EndsWith($"{PluginManager.BTCPayPluginSuffix}.json", StringComparison.InvariantCulture)).Select(async file => return await Task.WhenAll(files.Where(file => file.Name.EndsWith($"{PluginManager.BTCPayPluginSuffix}.json", StringComparison.InvariantCulture)).Select(async file =>
{ {
@@ -43,11 +43,11 @@ namespace BTCPayServer.Plugins
})); }));
} }
public async Task DownloadRemotePlugin(string remote, string plugin) public async Task DownloadRemotePlugin(string plugin)
{ {
var dest = _btcPayServerOptions.PluginDir; var dest = _btcPayServerOptions.PluginDir;
var resp = await _githubClient var resp = await _githubClient
.GetStringAsync(new Uri($"https://api.github.com/repos/{remote}/contents")); .GetStringAsync(new Uri($"https://api.github.com/repos/{_btcPayServerOptions.PluginRemote}/contents"));
var files = JsonConvert.DeserializeObject<GithubFile[]>(resp); var files = JsonConvert.DeserializeObject<GithubFile[]>(resp);
var ext = files.SingleOrDefault(file => file.Name == $"{plugin}{PluginManager.BTCPayPluginSuffix}"); var ext = files.SingleOrDefault(file => file.Name == $"{plugin}{PluginManager.BTCPayPluginSuffix}");
if (ext is null) if (ext is null)

View File

@@ -1,8 +1,10 @@
@using BTCPayServer.Configuration
@model BTCPayServer.Controllers.ServerController.ListPluginsViewModel @model BTCPayServer.Controllers.ServerController.ListPluginsViewModel
@inject BTCPayServerOptions BTCPayServerOptions
@{ @{
ViewData.SetActivePageAndTitle(ServerNavPages.Plugins); ViewData.SetActivePageAndTitle(ServerNavPages.Plugins);
var installed = Model.Installed.Select(plugin => plugin.Identifier); var installed = Model.Installed.Select(plugin => plugin.Identifier);
var availableAndNotInstalled = Model.Available.Where(plugin => !installed.Contains(plugin.Identifier)); var availableAndNotInstalled = Model.Available.Where(plugin => !installed.Contains(plugin.Identifier)).Select(plugin => (plugin, BTCPayServerOptions.RecommendedPlugins.Contains(plugin.Identifier.ToLowerInvariant()))).OrderBy(tuple => tuple.Item1);
} }
<partial name="_StatusMessage"/> <partial name="_StatusMessage"/>
@@ -58,7 +60,7 @@
{ {
@if (updateAvailable) @if (updateAvailable)
{ {
<form asp-action="InstallPlugin" asp-route-plugin="@plugin.Identifier" asp-route-remote="@Model.Remote" class="mr-3"> <form asp-action="InstallPlugin" asp-route-plugin="@plugin.Identifier" class="mr-3">
<button type="submit" class="btn btn-secondary">Update</button> <button type="submit" class="btn btn-secondary">Update</button>
</form> </form>
} }
@@ -77,13 +79,20 @@
{ {
<h3 class="mb-3">Available Plugins</h3> <h3 class="mb-3">Available Plugins</h3>
<div class="row mb-4"> <div class="row mb-4">
@foreach (var plugin in availableAndNotInstalled) @foreach (var pluginT in availableAndNotInstalled)
{ {
var plugin = pluginT.Item1;
<div class="col col-12 col-lg-6 mb-4"> <div class="col col-12 col-lg-6 mb-4">
<div class="card h-100"> <div class="card h-100">
<div class="card-body"> <div class="card-body">
<h4 class="card-title">@plugin.Name</h4> <h4 class="card-title">@plugin.Name</h4>
<h5 class="card-subtitle mb-3 text-muted">@plugin.Version</h5> <h5 class="card-subtitle mb-3 text-muted d-flex justify-content-between">
<span>@plugin.Version</span>
@if (pluginT.Item2)
{
<span data-toggle="tooltip" title="This plugin has been recommended to be installed by your deployment method.">Recommended <span class="fa fa-question-circle-o"></span></span>
}
</h5>
<p class="card-text">@plugin.Description</p> <p class="card-text">@plugin.Description</p>
</div> </div>
<div class="card-footer border-0 pb-3"> <div class="card-footer border-0 pb-3">
@@ -95,7 +104,7 @@
} }
else else
{ {
<form asp-action="InstallPlugin" asp-route-plugin="@plugin.Identifier" asp-route-remote="@Model.Remote"> <form asp-action="InstallPlugin" asp-route-plugin="@plugin.Identifier">
<button type="submit" class="btn btn-primary">Install</button> <button type="submit" class="btn btn-primary">Install</button>
</form> </form>
} }

View File

@@ -3,6 +3,7 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
WORKDIR /source WORKDIR /source
COPY nuget.config nuget.config COPY nuget.config nuget.config
COPY Build/Common.csproj Build/Common.csproj COPY Build/Common.csproj Build/Common.csproj
COPY BTCPayServer.Abstractions/BTCPayServer.Abstractions.csproj BTCPayServer.Abstractions/BTCPayServer.Abstractions.csproj
COPY BTCPayServer/BTCPayServer.csproj BTCPayServer/BTCPayServer.csproj COPY BTCPayServer/BTCPayServer.csproj BTCPayServer/BTCPayServer.csproj
COPY BTCPayServer.Common/BTCPayServer.Common.csproj BTCPayServer.Common/BTCPayServer.Common.csproj COPY BTCPayServer.Common/BTCPayServer.Common.csproj BTCPayServer.Common/BTCPayServer.Common.csproj
COPY BTCPayServer.Rating/BTCPayServer.Rating.csproj BTCPayServer.Rating/BTCPayServer.Rating.csproj COPY BTCPayServer.Rating/BTCPayServer.Rating.csproj BTCPayServer.Rating/BTCPayServer.Rating.csproj
@@ -13,6 +14,7 @@ COPY BTCPayServer.Common/. BTCPayServer.Common/.
COPY BTCPayServer.Rating/. BTCPayServer.Rating/. COPY BTCPayServer.Rating/. BTCPayServer.Rating/.
COPY BTCPayServer.Data/. BTCPayServer.Data/. COPY BTCPayServer.Data/. BTCPayServer.Data/.
COPY BTCPayServer.Client/. BTCPayServer.Client/. COPY BTCPayServer.Client/. BTCPayServer.Client/.
COPY BTCPayServer.Abstractions/. BTCPayServer.Abstractions/.
COPY BTCPayServer/. BTCPayServer/. COPY BTCPayServer/. BTCPayServer/.
COPY Build/Version.csproj Build/Version.csproj COPY Build/Version.csproj Build/Version.csproj
ARG CONFIGURATION_NAME=Release ARG CONFIGURATION_NAME=Release

View File

@@ -7,6 +7,7 @@ RUN apt-get update \
WORKDIR /source WORKDIR /source
COPY nuget.config nuget.config COPY nuget.config nuget.config
COPY Build/Common.csproj Build/Common.csproj COPY Build/Common.csproj Build/Common.csproj
COPY BTCPayServer.Abstractions/BTCPayServer.Abstractions.csproj BTCPayServer.Abstractions/BTCPayServer.Abstractions.csproj
COPY BTCPayServer/BTCPayServer.csproj BTCPayServer/BTCPayServer.csproj COPY BTCPayServer/BTCPayServer.csproj BTCPayServer/BTCPayServer.csproj
COPY BTCPayServer.Common/BTCPayServer.Common.csproj BTCPayServer.Common/BTCPayServer.Common.csproj COPY BTCPayServer.Common/BTCPayServer.Common.csproj BTCPayServer.Common/BTCPayServer.Common.csproj
COPY BTCPayServer.Rating/BTCPayServer.Rating.csproj BTCPayServer.Rating/BTCPayServer.Rating.csproj COPY BTCPayServer.Rating/BTCPayServer.Rating.csproj BTCPayServer.Rating/BTCPayServer.Rating.csproj
@@ -17,6 +18,7 @@ COPY BTCPayServer.Common/. BTCPayServer.Common/.
COPY BTCPayServer.Rating/. BTCPayServer.Rating/. COPY BTCPayServer.Rating/. BTCPayServer.Rating/.
COPY BTCPayServer.Data/. BTCPayServer.Data/. COPY BTCPayServer.Data/. BTCPayServer.Data/.
COPY BTCPayServer.Client/. BTCPayServer.Client/. COPY BTCPayServer.Client/. BTCPayServer.Client/.
COPY BTCPayServer.Abstractions/. BTCPayServer.Abstractions/.
COPY BTCPayServer/. BTCPayServer/. COPY BTCPayServer/. BTCPayServer/.
COPY Build/Version.csproj Build/Version.csproj COPY Build/Version.csproj Build/Version.csproj
ARG CONFIGURATION_NAME=Release ARG CONFIGURATION_NAME=Release

View File

@@ -8,6 +8,7 @@ RUN apt-get update \
WORKDIR /source WORKDIR /source
COPY nuget.config nuget.config COPY nuget.config nuget.config
COPY Build/Common.csproj Build/Common.csproj COPY Build/Common.csproj Build/Common.csproj
COPY BTCPayServer.Abstractions/BTCPayServer.Abstractions.csproj BTCPayServer.Abstractions/BTCPayServer.Abstractions.csproj
COPY BTCPayServer/BTCPayServer.csproj BTCPayServer/BTCPayServer.csproj COPY BTCPayServer/BTCPayServer.csproj BTCPayServer/BTCPayServer.csproj
COPY BTCPayServer.Common/BTCPayServer.Common.csproj BTCPayServer.Common/BTCPayServer.Common.csproj COPY BTCPayServer.Common/BTCPayServer.Common.csproj BTCPayServer.Common/BTCPayServer.Common.csproj
COPY BTCPayServer.Rating/BTCPayServer.Rating.csproj BTCPayServer.Rating/BTCPayServer.Rating.csproj COPY BTCPayServer.Rating/BTCPayServer.Rating.csproj BTCPayServer.Rating/BTCPayServer.Rating.csproj
@@ -18,6 +19,7 @@ COPY BTCPayServer.Common/. BTCPayServer.Common/.
COPY BTCPayServer.Rating/. BTCPayServer.Rating/. COPY BTCPayServer.Rating/. BTCPayServer.Rating/.
COPY BTCPayServer.Data/. BTCPayServer.Data/. COPY BTCPayServer.Data/. BTCPayServer.Data/.
COPY BTCPayServer.Client/. BTCPayServer.Client/. COPY BTCPayServer.Client/. BTCPayServer.Client/.
COPY BTCPayServer.Abstractions/. BTCPayServer.Abstractions/.
COPY BTCPayServer/. BTCPayServer/. COPY BTCPayServer/. BTCPayServer/.
COPY Build/Version.csproj Build/Version.csproj COPY Build/Version.csproj Build/Version.csproj
ARG CONFIGURATION_NAME=Release ARG CONFIGURATION_NAME=Release