From 9d4add767b2d575701ee836c79a24ec45379935d Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Wed, 30 Aug 2023 19:09:05 +0200 Subject: [PATCH] Make Liquid TextEncoder configurable (#4380) --- .../Elsa.WorkflowServer.Web/Program.cs | 5 ++++- .../Elsa.Liquid/Features/LiquidFeature.cs | 10 ++++++++- .../Elsa.Liquid/Options/FluidOptions.cs | 21 +++++++++++++++++++ .../Elsa.Liquid/Services/LiquidParser.cs | 4 ++++ .../Services/LiquidTemplateManager.cs | 8 +++---- 5 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/bundles/Elsa.WorkflowServer.Web/Program.cs b/src/bundles/Elsa.WorkflowServer.Web/Program.cs index edda8b3b2..80397f625 100644 --- a/src/bundles/Elsa.WorkflowServer.Web/Program.cs +++ b/src/bundles/Elsa.WorkflowServer.Web/Program.cs @@ -1,3 +1,5 @@ +using System.Text; +using System.Text.Encodings.Web; using Elsa.EntityFrameworkCore.Extensions; using Elsa.EntityFrameworkCore.Modules.Identity; using Elsa.EntityFrameworkCore.Modules.Management; @@ -9,6 +11,7 @@ using Elsa.MongoDb.Modules.Identity; using Elsa.MongoDb.Modules.Management; using Elsa.MongoDb.Modules.Runtime; using Elsa.WorkflowServer.Web; +using Fluid; using Microsoft.Data.Sqlite; using Proto.Persistence.Sqlite; using Proto.Persistence.SqlServer; @@ -115,7 +118,7 @@ services .UseWorkflowsApi(api => api.AddFastEndpointsAssembly()) .UseRealTimeWorkflows() .UseJavaScript(js => js.JintOptions = options => options.AllowClrAccess = true) - .UseLiquid() + .UseLiquid(liquid => liquid.FluidOptions = options => options.Encoder = NullEncoder.Default) .UseHttp(http => http.HttpEndpointAuthorizationHandler = sp => sp.GetRequiredService()) .UseEmail(email => email.ConfigureOptions = options => configuration.GetSection("Smtp").Bind(options)); }); diff --git a/src/modules/Elsa.Liquid/Features/LiquidFeature.cs b/src/modules/Elsa.Liquid/Features/LiquidFeature.cs index 23355845d..2f8f346e8 100644 --- a/src/modules/Elsa.Liquid/Features/LiquidFeature.cs +++ b/src/modules/Elsa.Liquid/Features/LiquidFeature.cs @@ -9,6 +9,7 @@ using Elsa.Liquid.Contracts; using Elsa.Liquid.Expressions; using Elsa.Liquid.Filters; using Elsa.Liquid.Handlers; +using Elsa.Liquid.Options; using Elsa.Liquid.Providers; using Elsa.Liquid.Services; using Microsoft.Extensions.DependencyInjection; @@ -28,9 +29,16 @@ public class LiquidFeature : FeatureBase { } + /// + /// Configures the Fluid options. + /// + public Action FluidOptions { get; set; } = _ => { }; + /// - public override void Configure() + public override void Apply() { + Services.Configure(FluidOptions); + Services .AddHandlersFrom() .AddSingleton() diff --git a/src/modules/Elsa.Liquid/Options/FluidOptions.cs b/src/modules/Elsa.Liquid/Options/FluidOptions.cs index ecf47d590..ff94ae5e7 100644 --- a/src/modules/Elsa.Liquid/Options/FluidOptions.cs +++ b/src/modules/Elsa.Liquid/Options/FluidOptions.cs @@ -1,10 +1,31 @@ +using System.Text.Encodings.Web; using Elsa.Liquid.Services; +using Fluid; namespace Elsa.Liquid.Options; +/// +/// Options for configuring the Liquid templating engine. +/// public class FluidOptions { + /// + /// A dictionary of filter registrations. + /// public Dictionary FilterRegistrations { get; } = new(); + + /// + /// A list of parser configurations. + /// public IList> ParserConfiguration { get; } = new List>(); + + /// + /// Gets or sets a value indicating whether to allow access to the configuration object. + /// public bool AllowConfigurationAccess { get; set; } + + /// + /// Gets or sets the default encoder to use when rendering a template. + /// + public TextEncoder Encoder { get; set; } = NullEncoder.Default; } \ No newline at end of file diff --git a/src/modules/Elsa.Liquid/Services/LiquidParser.cs b/src/modules/Elsa.Liquid/Services/LiquidParser.cs index 9e375c47a..62a1c5cf4 100644 --- a/src/modules/Elsa.Liquid/Services/LiquidParser.cs +++ b/src/modules/Elsa.Liquid/Services/LiquidParser.cs @@ -4,8 +4,12 @@ using Microsoft.Extensions.Options; namespace Elsa.Liquid.Services; +/// +/// A parser for the Liquid templating engine. +/// public class LiquidParser : FluidParser { + /// public LiquidParser(IOptions options) { foreach (var configuration in options.Value.ParserConfiguration) diff --git a/src/modules/Elsa.Liquid/Services/LiquidTemplateManager.cs b/src/modules/Elsa.Liquid/Services/LiquidTemplateManager.cs index 3665cc296..a2d782cc0 100644 --- a/src/modules/Elsa.Liquid/Services/LiquidTemplateManager.cs +++ b/src/modules/Elsa.Liquid/Services/LiquidTemplateManager.cs @@ -1,5 +1,4 @@ -using System.Text.Encodings.Web; -using Elsa.Expressions.Models; +using Elsa.Expressions.Models; using Elsa.Extensions; using Elsa.Liquid.Contracts; using Elsa.Liquid.Notifications; @@ -22,7 +21,7 @@ public class LiquidTemplateManager : ILiquidTemplateManager /// /// Constructor. /// - public LiquidTemplateManager(LiquidParser parser, IMemoryCache memoryCache, INotificationSender notificationSender, IOptions options, IServiceProvider serviceProvider) + public LiquidTemplateManager(LiquidParser parser, IMemoryCache memoryCache, INotificationSender notificationSender, IOptions options) { _parser = parser; _memoryCache = memoryCache; @@ -38,9 +37,10 @@ public class LiquidTemplateManager : ILiquidTemplateManager var result = GetCachedTemplate(template); var templateContext = await CreateTemplateContextAsync(expressionExecutionContext, cancellationToken); + var encoder = _options.Encoder; templateContext.AddFilters(_options, expressionExecutionContext.ServiceProvider); - return await result.RenderAsync(templateContext, HtmlEncoder.Default); + return await result.RenderAsync(templateContext, encoder); } private IFluidTemplate GetCachedTemplate(string source)