Files
btcpayserver/BTCPayServer/Filters/DomainMappingConstraintAttribute.cs
Andrew Camilleri f74ea14d8b Plugins can now build apps (#4608)
* Plugins can now build apps

* fix tests

* fixup

* pluginize existing apps

* Test fixes part 1

* Test fixes part 2

* Fix Crowdfund namespace

* Syntax

* More namespace fixes

* Markup

* Test fix

* upstream fixes

* Add plugin icon

* Fix nullable build warnings

* allow pre popualting app creation

* Fixes after merge

* Make link methods async

* Use AppData as parameter for ConfigureLink

* GetApps by AppType

* Use ConfigureLink on dashboard

* Rename method

* Add properties to indicate stats support

* Property updates

* Test fixes

* Clean up imports

* Fixes after merge

---------

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2023-03-17 11:56:32 +09:00

77 lines
2.9 KiB
C#

using System;
using System.Linq;
using BTCPayServer.Services;
using BTCPayServer.Services.Apps;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.Extensions.DependencyInjection;
namespace BTCPayServer.Filters
{
public class DomainMappingConstraintAttribute : Attribute, IActionConstraint
{
public DomainMappingConstraintAttribute()
{
}
public DomainMappingConstraintAttribute(string appType)
{
AppType = appType;
}
public int Order => 100;
private string AppType { get; }
public bool Accept(ActionConstraintContext context)
{
var hasAppId = context.RouteContext.RouteData.Values.ContainsKey("appId");
var policies = context.RouteContext.HttpContext.RequestServices.GetService<PoliciesSettings>();
var mapping = policies?.DomainToAppMapping;
var hasDomainMapping = mapping is { Count: > 0 };
if (hasAppId && hasDomainMapping)
{
var appId = (string)context.RouteContext.RouteData.Values["appId"];
var matchedDomainMapping = mapping.FirstOrDefault(item => item.AppId == appId);
// App is accessed via path, redirect to canonical domain
var req = context.RouteContext.HttpContext.Request;
if (matchedDomainMapping != null && req.Method != "POST" && !req.HasFormContentType)
{
var uri = new UriBuilder(req.Scheme, matchedDomainMapping.Domain);
if (req.Host.Port.HasValue) uri.Port = req.Host.Port.Value;
context.RouteContext.HttpContext.Response.Redirect(uri.ToString());
return true;
}
}
if (hasDomainMapping)
{
var matchedDomainMapping = mapping.FirstOrDefault(item =>
item.Domain.Equals(context.RouteContext.HttpContext.Request.Host.Host,
StringComparison.InvariantCultureIgnoreCase));
if (matchedDomainMapping != null)
{
if (AppType is not { } appType)
return false;
if (appType != matchedDomainMapping.AppType)
return false;
if (!hasAppId)
{
context.RouteContext.RouteData.Values.Add("appId", matchedDomainMapping.AppId);
return true;
}
}
}
if (AppType == policies.RootAppType && !hasAppId && !string.IsNullOrEmpty(policies.RootAppId))
{
context.RouteContext.RouteData.Values.Add("appId", policies.RootAppId);
return true;
}
return hasAppId || AppType is null;
}
}
}