From bc0f780472fb5b4622e1609e661b4cf73c325b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Mon, 22 Jul 2024 23:39:35 +0200 Subject: [PATCH] Adding an IContentSecurityPolicyProvider to allow tenant admin login --- .../Filters/TenantsIndexFilter.cs | 16 ++++---- .../TenantLoginSecurityPolicyProvider.cs | 40 +++++++++++++++++++ Lombiq.Hosting.Tenants.Admin.Login/Startup.cs | 1 + 3 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 Lombiq.Hosting.Tenants.Admin.Login/Services/TenantLoginSecurityPolicyProvider.cs diff --git a/Lombiq.Hosting.Tenants.Admin.Login/Filters/TenantsIndexFilter.cs b/Lombiq.Hosting.Tenants.Admin.Login/Filters/TenantsIndexFilter.cs index 99302312..b0066196 100644 --- a/Lombiq.Hosting.Tenants.Admin.Login/Filters/TenantsIndexFilter.cs +++ b/Lombiq.Hosting.Tenants.Admin.Login/Filters/TenantsIndexFilter.cs @@ -38,18 +38,11 @@ public TenantsIndexFilter( public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) { - var actionRouteController = context.ActionDescriptor.RouteValues["Controller"]; - var actionRouteArea = context.ActionDescriptor.RouteValues["Area"]; - var actionRouteValue = context.ActionDescriptor.RouteValues["Action"]; - - if (actionRouteController == typeof(AdminController).ControllerName() && - actionRouteArea == $"{nameof(OrchardCore)}.{nameof(OrchardCore.Tenants)}" && - actionRouteValue is nameof(AdminController.Edit) && + if (IsTenantsEditAction(context) && context.Result is ViewResult && await _authorizationService.AuthorizeAsync( _hca.HttpContext.User, - TenantAdminPermissions.LoginAsAdmin) - ) + TenantAdminPermissions.LoginAsAdmin)) { var shellSettings = _shellHost.GetSettings(context.RouteData.Values["Id"].ToString()); if (shellSettings != null && @@ -70,4 +63,9 @@ await contentZone.AddAsync( await next(); } + + public static bool IsTenantsEditAction(ActionContext context) => + context.ActionDescriptor.RouteValues["Controller"] == typeof(AdminController).ControllerName() && + context.ActionDescriptor.RouteValues["Area"] == $"{nameof(OrchardCore)}.{nameof(OrchardCore.Tenants)}" && + context.ActionDescriptor.RouteValues["Action"] is nameof(AdminController.Edit); } diff --git a/Lombiq.Hosting.Tenants.Admin.Login/Services/TenantLoginSecurityPolicyProvider.cs b/Lombiq.Hosting.Tenants.Admin.Login/Services/TenantLoginSecurityPolicyProvider.cs new file mode 100644 index 00000000..e7434add --- /dev/null +++ b/Lombiq.Hosting.Tenants.Admin.Login/Services/TenantLoginSecurityPolicyProvider.cs @@ -0,0 +1,40 @@ +using Lombiq.HelpfulLibraries.AspNetCore.Security; +using Lombiq.Hosting.Tenants.Admin.Login.Filters; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Infrastructure; +using OrchardCore.Environment.Shell; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Lombiq.Hosting.Tenants.Admin.Login.Services; + +internal sealed class TenantLoginSecurityPolicyProvider : IContentSecurityPolicyProvider +{ + private readonly IActionContextAccessor _actionContextAccessor; + private readonly IShellHost _shellHost; + + public TenantLoginSecurityPolicyProvider(IActionContextAccessor actionContextAccessor, IShellHost shellHost) + { + _actionContextAccessor = actionContextAccessor; + _shellHost = shellHost; + } + + public ValueTask UpdateAsync(IDictionary securityPolicies, HttpContext context) + { + var actionContext = _actionContextAccessor.ActionContext; + + if (!TenantsIndexFilter.IsTenantsEditAction(actionContext)) + { + return ValueTask.CompletedTask; + } + + var shellName = actionContext.RouteData.Values["Id"].ToString(); + + if (_shellHost.TryGetSettings(shellName, out var shellSettings)) + { + CspHelper.MergeValues(securityPolicies, ContentSecurityPolicyDirectives.FormAction, shellSettings.RequestUrlHosts); + } + + return ValueTask.CompletedTask; + } +} diff --git a/Lombiq.Hosting.Tenants.Admin.Login/Startup.cs b/Lombiq.Hosting.Tenants.Admin.Login/Startup.cs index 37d28b21..bc7a4b6f 100644 --- a/Lombiq.Hosting.Tenants.Admin.Login/Startup.cs +++ b/Lombiq.Hosting.Tenants.Admin.Login/Startup.cs @@ -17,5 +17,6 @@ public override void ConfigureServices(IServiceCollection services) services.Configure(options => options.Filters.Add(typeof(TenantsIndexFilter))); services.AddScoped(); services.AddSingleton(); + services.AddContentSecurityPolicyProvider(); } }