#8862: Preventing the SQL Server Service Broker feature from being enabled when not using SQL Server (Lombiq Technologies: ORCH-309) (#8875)
Build Crowdin Translation Packages / build-crowdin-translation-packages (push) Has been cancelled
Compile / Compile .NET solution (push) Has been cancelled
Compile / Compile Client-side Assets (push) Has been cancelled
SpecFlow Tests / SpecFlow Tests (push) Has been cancelled

This commit is contained in:
Milán Keszthelyi
2025-12-09 00:05:04 +01:00
committed by GitHub
parent d9d071115c
commit 165505b1db
2 changed files with 97 additions and 0 deletions
@@ -130,6 +130,7 @@
<Compile Include="Services\IHostNameProvider.cs" />
<Compile Include="Services\MessageBusNotificationProvider.cs" />
<Compile Include="Handler\MessageBusHandler.cs" />
<Compile Include="Services\SqlServerServiceBrokerFeatureGuard.cs" />
<Compile Include="SqlServerBrokerMigrations.cs" />
<Compile Include="Models\MessageRecord.cs" />
<Compile Include="Services\DefaultMessageBus.cs" />
@@ -0,0 +1,96 @@
using System;
using System.Web.Mvc;
using Orchard.Environment;
using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions.Models;
using Orchard.Environment.Features;
using Orchard.Localization;
using Orchard.Mvc;
using Orchard.Mvc.Filters;
using Orchard.UI.Notify;
namespace Orchard.MessageBus.Services
{
/// <summary>
/// Prevents the SQL Server Service Broker feature from being enabled for tenants that are not using Microsoft SQL
/// Server as their database provider.
/// </summary>
/// <remarks>
/// The implementation is hackish but there seems to be no other way: if it would use <see cref="INotifier"/> it
/// wouldn't work since <see cref="NotifyFilter"/> that writes out notifications to TempData runs before feature
/// events are raised. Thus we have to manually add the messages to TempData, just as the filter would do.
/// </remarks>
public class SqlServerServiceBrokerFeatureGuard : FilterProvider, IFeatureEventHandler, IActionFilter
{
private const string FeatureId = "Orchard.MessageBus.SqlServerServiceBroker";
private const string TempDataKey = FeatureId + ".TempData";
private readonly ShellSettings _shellSettings;
private readonly IFeatureManager _featureManager;
private readonly IHttpContextAccessor _hca;
public Localizer T { get; set; }
public SqlServerServiceBrokerFeatureGuard(
ShellSettings shellSettings,
IFeatureManager featureManager,
IHttpContextAccessor hca)
{
_shellSettings = shellSettings;
_featureManager = featureManager;
_hca = hca;
T = NullLocalizer.Instance;
}
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { }
void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
{
var httpContext = _hca.Current();
if (httpContext == null) return;
httpContext.Items[TempDataKey] = filterContext.Controller.TempData;
}
public void Installing(Feature feature) { }
public void Installed(Feature feature) { }
public void Enabling(Feature feature) { }
public void Enabled(Feature feature)
{
if (feature.Descriptor.Id != FeatureId)
return;
if (!_shellSettings.DataProvider.Equals("SqlServer", StringComparison.OrdinalIgnoreCase))
{
_featureManager.DisableFeatures(new[] { FeatureId }, force: true);
AddNotification(
T("The SQL Server Service Broker cannot be enabled because it requires Microsoft SQL Server."),
NotifyType.Error);
}
}
public void Disabling(Feature feature) { }
public void Disabled(Feature feature) { }
public void Uninstalling(Feature feature) { }
public void Uninstalled(Feature feature) { }
private void AddNotification(LocalizedString message, NotifyType notifyType = NotifyType.Warning)
{
var tempDataDictionary = _hca.Current()?.Items[TempDataKey];
if (tempDataDictionary == null) return;
((TempDataDictionary)tempDataDictionary)["messages"] +=
$"{notifyType}:{message.Text}{System.Environment.NewLine}-{System.Environment.NewLine}";
}
}
}