diff --git a/BTCPayServer/Hosting/Startup.cs b/BTCPayServer/Hosting/Startup.cs index da9c617c6..23ff4d249 100644 --- a/BTCPayServer/Hosting/Startup.cs +++ b/BTCPayServer/Hosting/Startup.cs @@ -140,6 +140,7 @@ namespace BTCPayServer.Hosting .AddRazorRuntimeCompilation() .AddPlugins(services, Configuration, LoggerFactory) .AddControllersAsServices(); + ValidateControllerNameTransformer.Register(services); services.TryAddScoped(); services.Configure(options => @@ -268,7 +269,7 @@ namespace BTCPayServer.Hosting PaymentRequestHub.Register(endpoints); endpoints.MapRazorPages(); endpoints.MapControllers(); - endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); + endpoints.MapControllerRoute("default", "{controller:validate=Home}/{action=Index}/{id?}"); }); app.UsePlugins(); } diff --git a/BTCPayServer/Hosting/ValidateControllerNameTransformer.cs b/BTCPayServer/Hosting/ValidateControllerNameTransformer.cs new file mode 100644 index 000000000..fe0516207 --- /dev/null +++ b/BTCPayServer/Hosting/ValidateControllerNameTransformer.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.ApplicationModels; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.DependencyInjection; + +namespace BTCPayServer.Hosting +{ + public class ValidateControllerNameTransformer : IOutboundParameterTransformer + { + public static void Register(IServiceCollection services) + { + services.AddRouting(opts => + { + opts.ConstraintMap["validate"] = typeof(ValidateControllerNameTransformer); + }); + services.AddTransient(); + services.AddSingleton(); + } + public class ControllerNotFoundException : Exception + { + public ControllerNotFoundException(string controllerName) : base($"The controller {controllerName} has not been found") + { + + } + } + public class ControllerNameList : HashSet + { + + } + public class ApplicitionModelProvider : IApplicationModelProvider + { + public ApplicitionModelProvider(ControllerNameList list) + { + List = list; + } + public int Order => 0; + + public ControllerNameList List { get; } + + public void OnProvidersExecuted(ApplicationModelProviderContext context) + { + if (List.Count != 0) + return; + lock (List) + { + foreach (var controller in context.Result.Controllers) + { + List.Add(controller.ControllerName); + } + } + } + + public void OnProvidersExecuting(ApplicationModelProviderContext context) + { + + } + } + + private readonly ControllerNameList list; + public ValidateControllerNameTransformer(ControllerNameList list) + { + this.list = list; + } + public string TransformOutbound(object value) + { + if (value is not string str) + return null; + if (!list.Contains(str)) + throw new ControllerNotFoundException(str); + return str; + } + } + + +}