From 3174e65d945cedc1ac22a33a80cf9992f0aa06c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Mon, 29 Jul 2024 23:47:57 +0200 Subject: [PATCH 01/18] Adding ConfigureHostingDefaults basics --- .../Docs/Extensions.md | 1 + .../ConfigurationSectionExtensions.cs | 21 ++++++ .../OrchardCoreBuilderExtensions.cs | 72 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 Lombiq.HelpfulLibraries.AspNetCore/Extensions/ConfigurationSectionExtensions.cs diff --git a/Lombiq.HelpfulLibraries.AspNetCore/Docs/Extensions.md b/Lombiq.HelpfulLibraries.AspNetCore/Docs/Extensions.md index 86bdcb4d..0dccc3ab 100644 --- a/Lombiq.HelpfulLibraries.AspNetCore/Docs/Extensions.md +++ b/Lombiq.HelpfulLibraries.AspNetCore/Docs/Extensions.md @@ -1,5 +1,6 @@ # Lombiq Helpful Libraries - ASP.NET Core Libraries - Extensions +- `ConfigurationSectionExtensions`: Provides shortcuts for `IConfigurationSection` operations. - `CookieHttpContextExtensions`: Provides shortcuts for some cookie-related operations. - `DateTimeHttpContextExtensions`: Makes it possible to set or get IANA time-zone IDs in the HTTP context. - `EnvironmentHttpContextExtensions`: Provides shortcuts to determine information about the current hosting environment, like whether the app is running in Development mode. diff --git a/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ConfigurationSectionExtensions.cs b/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ConfigurationSectionExtensions.cs new file mode 100644 index 00000000..dc972ff5 --- /dev/null +++ b/Lombiq.HelpfulLibraries.AspNetCore/Extensions/ConfigurationSectionExtensions.cs @@ -0,0 +1,21 @@ +namespace Microsoft.Extensions.Configuration; + +/// +/// Shortcuts for operations. +/// +public static class ConfigurationSectionExtensions +{ + /// + /// Adds a value to a configuration section if the key doesn't exist yet. + /// + /// The key of the configuration. + /// The value of the configuration. + public static IConfigurationSection AddValueIfKeyNotExists( + this IConfigurationSection configurationSection, + string key, + string value) + { + configurationSection[key] ??= value; + return configurationSection; + } +} diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs index 3e611531..0a2a2550 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs @@ -1,4 +1,6 @@ +using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; using OrchardCore.Email; using OrchardCore.Environment.Shell.Configuration; using OrchardCore.ResourceManagement; @@ -58,4 +60,74 @@ public static OrchardCoreBuilder ConfigureSmtpSettings( public static OrchardCoreBuilder DisableResourceDebugMode(this OrchardCoreBuilder builder) => builder.ConfigureServices((tenantServices, _) => tenantServices.PostConfigure(settings => settings.DebugMode = false)); + + /// + /// Recommended default configuration for features of a standard Orchard Core application. If any of the + /// configuration values exist, they won't be overridden, so e.g. appsettings.json configuration will take + /// precedence. + /// + /// The instance of the app. + public static OrchardCoreBuilder ConfigureHostingDefaults( + this OrchardCoreBuilder builder, + WebApplicationBuilder webApplicationBuilder) + { + var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); + + ocSection.GetSection("OrchardCore_Tenants").AddValueIfKeyNotExists("TenantRemovalAllowed", "true"); + + if (webApplicationBuilder.Environment.IsDevelopment()) + { + // Orchard Core 1.8 and prior, this can be removed after an Orchard Core upgrade to 2.0. + // OrchardCore_Email_Smtp below is 2.0+. + var oc18SmtpSection = ocSection.GetSection("SmtpSettings"); + + if (oc18SmtpSection["Host"] == null) + { + oc18SmtpSection["Host"] = "127.0.0.1"; + oc18SmtpSection["RequireCredentials"] = "false"; + oc18SmtpSection["Port"] = "25"; + } + + oc18SmtpSection.AddValueIfKeyNotExists("DefaultSender", "sender@example.com"); + + var smtpSection = ocSection.GetSection("OrchardCore_Email_Smtp"); + + if (smtpSection["Host"] == null) + { + smtpSection["Host"] = "127.0.0.1"; + smtpSection["RequireCredentials"] = "false"; + smtpSection["Port"] = "25"; + } + + smtpSection.AddValueIfKeyNotExists("DefaultSender", "sender@example.com"); + } + + builder.AddDatabaseShellsConfigurationIfAvailable(webApplicationBuilder.Configuration); + + return builder; + } + + /// + /// Recommended default configuration for features of an Orchard Core application hosted in Azure. If any of the + /// configuration values exist, they won't be overridden, so e.g. appsettings.json configuration will take + /// precedence. + /// + /// The instance of the app. + public static OrchardCoreBuilder ConfigureAzureHostingDefaults( + this OrchardCoreBuilder builder, + WebApplicationBuilder webApplicationBuilder) + { + builder.ConfigureHostingDefaults(webApplicationBuilder); + + var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); + + if (webApplicationBuilder.Environment.IsDevelopment()) + { + var appInsightsSection = webApplicationBuilder.Configuration.GetSection("ApplicationInsights"); + + appInsightsSection.AddValueIfKeyNotExists("EnableDependencyTrackingTelemetryModule", "false"); + } + + return builder; + } } From d70a0bbfc1b33a773e2dcfd459a8646a3cfe21ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 00:39:58 +0200 Subject: [PATCH 02/18] Finalizing SMTP configuration --- .../Environment/OrchardCoreBuilderExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs index 0a2a2550..d6a8085e 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs @@ -102,7 +102,9 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( smtpSection.AddValueIfKeyNotExists("DefaultSender", "sender@example.com"); } - builder.AddDatabaseShellsConfigurationIfAvailable(webApplicationBuilder.Configuration); + builder + .AddDatabaseShellsConfigurationIfAvailable(webApplicationBuilder.Configuration) + .ConfigureSmtpSettings(overrideAdminSettings: false); return builder; } @@ -123,9 +125,7 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( if (webApplicationBuilder.Environment.IsDevelopment()) { - var appInsightsSection = webApplicationBuilder.Configuration.GetSection("ApplicationInsights"); - appInsightsSection.AddValueIfKeyNotExists("EnableDependencyTrackingTelemetryModule", "false"); } return builder; From 02280516af7eb501b8fb69707ab1f7ca88fa6d78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 00:45:16 +0200 Subject: [PATCH 03/18] Adding ConfigureSecurityDefaultsWithStaticFiles() call to hosting defaults --- .../Environment/OrchardCoreBuilderExtensions.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs index d6a8085e..1cd15dd5 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs @@ -104,7 +104,8 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( builder .AddDatabaseShellsConfigurationIfAvailable(webApplicationBuilder.Configuration) - .ConfigureSmtpSettings(overrideAdminSettings: false); + .ConfigureSmtpSettings(overrideAdminSettings: false) + .ConfigureSecurityDefaultsWithStaticFiles(allowInlineStyle: true); return builder; } From de489bacd3f5262379dd805dbb694e478df09da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 00:56:14 +0200 Subject: [PATCH 04/18] Enabling Azure Data Protection and BuildVersionDisplay in hosting defaults --- .../Environment/OrchardCoreBuilderExtensions.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs index 1cd15dd5..93616245 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs @@ -124,9 +124,11 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); - if (webApplicationBuilder.Environment.IsDevelopment()) + if (webApplicationBuilder.Configuration.IsAzureHosting()) { - + builder.AddTenantFeatures( + "OrchardCore.DataProtection.Azure", + "Lombiq.Hosting.BuildVersionDisplay"); } return builder; From fc8c719391a4875129dad3737102f5327d7530d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 00:57:46 +0200 Subject: [PATCH 05/18] Adding DisableResourceDebugMode() to hosting defaults --- .../Environment/OrchardCoreBuilderExtensions.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs index 93616245..76a9aef5 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs @@ -126,9 +126,11 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( if (webApplicationBuilder.Configuration.IsAzureHosting()) { - builder.AddTenantFeatures( - "OrchardCore.DataProtection.Azure", - "Lombiq.Hosting.BuildVersionDisplay"); + builder + .AddTenantFeatures( + "OrchardCore.DataProtection.Azure", + "Lombiq.Hosting.BuildVersionDisplay") + .DisableResourceDebugMode(); } return builder; From d64d3f828c1206fe5d104b8075e0dd0329c14097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 01:10:49 +0200 Subject: [PATCH 06/18] Adding Azure Media Storage and Health Checks enable to hosting defaults --- .../OrchardCoreBuilderExtensions.cs | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs index 76a9aef5..4b1e9ba8 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs @@ -67,9 +67,13 @@ public static OrchardCoreBuilder DisableResourceDebugMode(this OrchardCoreBuilde /// precedence. /// /// The instance of the app. + /// + /// Indicates whether to enable OrchardCore.HealthChecks in the Production environment. + /// public static OrchardCoreBuilder ConfigureHostingDefaults( this OrchardCoreBuilder builder, - WebApplicationBuilder webApplicationBuilder) + WebApplicationBuilder webApplicationBuilder, + bool enableHealthChecksInProduction = true) { var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); @@ -102,6 +106,11 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( smtpSection.AddValueIfKeyNotExists("DefaultSender", "sender@example.com"); } + if (enableHealthChecksInProduction && webApplicationBuilder.Environment.IsProduction()) + { + builder.AddTenantFeatures("OrchardCore.HealthChecks"); + } + builder .AddDatabaseShellsConfigurationIfAvailable(webApplicationBuilder.Configuration) .ConfigureSmtpSettings(overrideAdminSettings: false) @@ -116,9 +125,17 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( /// precedence. /// /// The instance of the app. + /// + /// Indicates whether to enable OrchardCore.Media.Azure.Storage and its dependencies when hosted in Azure. + /// + /// + /// Indicates whether to enable OrchardCore.HealthChecks in the Production environment. + /// public static OrchardCoreBuilder ConfigureAzureHostingDefaults( this OrchardCoreBuilder builder, - WebApplicationBuilder webApplicationBuilder) + WebApplicationBuilder webApplicationBuilder, + bool enableAzureMediaStorage = true, + bool enableHealthChecksInProduction = true) { builder.ConfigureHostingDefaults(webApplicationBuilder); @@ -131,6 +148,19 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( "OrchardCore.DataProtection.Azure", "Lombiq.Hosting.BuildVersionDisplay") .DisableResourceDebugMode(); + + if (enableAzureMediaStorage) + { + // Azure Media Storage and its dependencies. Keep this updated with Orchard upgrades. + builder.AddTenantFeatures( + "OrchardCore.Contents", + "OrchardCore.ContentTypes", + "OrchardCore.Liquid", + "OrchardCore.Media", + "OrchardCore.Media.Azure.Storage", + "OrchardCore.Media.Cache", + "OrchardCore.Settings"); + } } return builder; From d87852f8cb0a045a02cc5b2af688857d030e7e18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 02:22:32 +0200 Subject: [PATCH 07/18] Adding logging config to hosting defaults --- .../Environment/OrchardCoreBuilderExtensions.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs index 4b1e9ba8..94347ac6 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs @@ -79,8 +79,15 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( ocSection.GetSection("OrchardCore_Tenants").AddValueIfKeyNotExists("TenantRemovalAllowed", "true"); + var logLevelSection = webApplicationBuilder.Configuration.GetSection("Logging:LogLevel"); + if (webApplicationBuilder.Environment.IsDevelopment()) { + logLevelSection + .AddValueIfKeyNotExists("Default", "Debug") + .AddValueIfKeyNotExists("System", "Information") + .AddValueIfKeyNotExists("Microsoft", "Information"); + // Orchard Core 1.8 and prior, this can be removed after an Orchard Core upgrade to 2.0. // OrchardCore_Email_Smtp below is 2.0+. var oc18SmtpSection = ocSection.GetSection("SmtpSettings"); @@ -105,6 +112,12 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( smtpSection.AddValueIfKeyNotExists("DefaultSender", "sender@example.com"); } + else + { + logLevelSection + .AddValueIfKeyNotExists("Default", "Warning") + .AddValueIfKeyNotExists("Microsoft.AspNetCore", "Warning"); + } if (enableHealthChecksInProduction && webApplicationBuilder.Environment.IsProduction()) { @@ -139,8 +152,6 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( { builder.ConfigureHostingDefaults(webApplicationBuilder); - var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); - if (webApplicationBuilder.Configuration.IsAzureHosting()) { builder From 335e4a2647416ccc268185cd9182f4e4ae57f3cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 16:51:51 +0200 Subject: [PATCH 08/18] Adding OrchardCore_DataProtection_Azure defaults --- .../OrchardCoreBuilderExtensions.cs | 66 +++++++++++++------ 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs index 94347ac6..d986cb16 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs @@ -62,19 +62,22 @@ public static OrchardCoreBuilder DisableResourceDebugMode(this OrchardCoreBuilde tenantServices.PostConfigure(settings => settings.DebugMode = false)); /// - /// Recommended default configuration for features of a standard Orchard Core application. If any of the - /// configuration values exist, they won't be overridden, so e.g. appsettings.json configuration will take + /// Lombiq-recommended opinionated default configuration for features of a standard Orchard Core application. If any + /// of the configuration values exist, they won't be overridden, so e.g. appsettings.json configuration will take /// precedence. /// /// The instance of the app. - /// - /// Indicates whether to enable OrchardCore.HealthChecks in the Production environment. - /// + /// Configuration for the hosting defaults. public static OrchardCoreBuilder ConfigureHostingDefaults( this OrchardCoreBuilder builder, WebApplicationBuilder webApplicationBuilder, - bool enableHealthChecksInProduction = true) + HostingConfiguration hostingConfiguration = null) { + hostingConfiguration ??= new HostingConfiguration(); + + // Not using static type references for the names here because those practically never change, but we'd need to + // add project/package references to all the affected projects. + var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); ocSection.GetSection("OrchardCore_Tenants").AddValueIfKeyNotExists("TenantRemovalAllowed", "true"); @@ -119,7 +122,7 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( .AddValueIfKeyNotExists("Microsoft.AspNetCore", "Warning"); } - if (enableHealthChecksInProduction && webApplicationBuilder.Environment.IsProduction()) + if (hostingConfiguration.EnableHealthChecksInProduction && webApplicationBuilder.Environment.IsProduction()) { builder.AddTenantFeatures("OrchardCore.HealthChecks"); } @@ -133,24 +136,22 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( } /// - /// Recommended default configuration for features of an Orchard Core application hosted in Azure. If any of the - /// configuration values exist, they won't be overridden, so e.g. appsettings.json configuration will take - /// precedence. + /// Lombiq-recommended opinionated default configuration for features of an Orchard Core application hosted in + /// Azure. If any of the configuration values exist, they won't be overridden, so e.g. appsettings.json + /// configuration will take precedence. /// /// The instance of the app. - /// - /// Indicates whether to enable OrchardCore.Media.Azure.Storage and its dependencies when hosted in Azure. - /// - /// - /// Indicates whether to enable OrchardCore.HealthChecks in the Production environment. - /// + /// Configuration for the hosting defaults. public static OrchardCoreBuilder ConfigureAzureHostingDefaults( this OrchardCoreBuilder builder, WebApplicationBuilder webApplicationBuilder, - bool enableAzureMediaStorage = true, - bool enableHealthChecksInProduction = true) + AzureHostingConfiguration hostingConfiguration = null) { - builder.ConfigureHostingDefaults(webApplicationBuilder); + hostingConfiguration ??= new AzureHostingConfiguration(); + + builder.ConfigureHostingDefaults(webApplicationBuilder, hostingConfiguration); + + var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); if (webApplicationBuilder.Configuration.IsAzureHosting()) { @@ -160,7 +161,7 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( "Lombiq.Hosting.BuildVersionDisplay") .DisableResourceDebugMode(); - if (enableAzureMediaStorage) + if (hostingConfiguration.EnableAzureMediaStorage) { // Azure Media Storage and its dependencies. Keep this updated with Orchard upgrades. builder.AddTenantFeatures( @@ -174,6 +175,31 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( } } + if (webApplicationBuilder.Environment.IsDevelopment()) + { + var dataProtectionSection = ocSection.GetSection("OrchardCore_DataProtection_Azure"); + + dataProtectionSection.AddValueIfKeyNotExists("CreateContainer", "true"); + dataProtectionSection.AddValueIfKeyNotExists("ConnectionString", "UseDevelopmentStorage=true"); + } + return builder; } } + +public class HostingConfiguration +{ + /// + /// Gets or sets a value indicating whether to enable OrchardCore.HealthChecks in the Production environment. + /// + public bool EnableHealthChecksInProduction { get; set; } = true; +} + +public class AzureHostingConfiguration : HostingConfiguration +{ + /// + /// Gets or sets a value indicating whether to enable OrchardCore.Media.Azure.Storage and its + /// dependencies when hosted in Azure. + /// + public bool EnableAzureMediaStorage { get; set; } = true; +} From 5504c3be937447ee11f3fd5a2a888143764aee1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 17:00:06 +0200 Subject: [PATCH 09/18] Factoring out hosting defaults to separate class --- .../Docs/Environment.md | 1 + ...ingDefaultsOrchardCoreBuilderExtensions.cs | 150 ++++++++++++++++++ .../OrchardCoreBuilderExtensions.cs | 144 ----------------- 3 files changed, 151 insertions(+), 144 deletions(-) create mode 100644 Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Docs/Environment.md b/Lombiq.HelpfulLibraries.OrchardCore/Docs/Environment.md index 5f008f48..94ce8989 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Docs/Environment.md +++ b/Lombiq.HelpfulLibraries.OrchardCore/Docs/Environment.md @@ -3,5 +3,6 @@ ## Extensions - `FeatureInfoEnumerableExtensions`: Shortcuts for `IEnumerable`, like `Any(featureId)`. +- `HostingDefaultsOrchardCoreBuilderExtensions`: Lombiq-recommended opinionated default configuration for features of a standard Orchard Core application, including one hosted in Azure. It substitutes much of what you'd write as configuration in a `Program` class or _appsettings.json_ files. - `OrchardCoreBuilderExtensions`: Shortcuts that can be used when initializing Orchard with `OrchardCoreBuilder`, e.g. `AddOrchardCms()`. - `ShellFeaturesManagerExtensions`: Shortcuts for `IShellFeaturesManager`, like `IsFeatureEnabledAsync()`. diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs new file mode 100644 index 00000000..661aa7ce --- /dev/null +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs @@ -0,0 +1,150 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; + +namespace Microsoft.Extensions.DependencyInjection; + +public static class HostingDefaultsOrchardCoreBuilderExtensions +{ + /// + /// Lombiq-recommended opinionated default configuration for features of a standard Orchard Core application. If + /// any of the configuration values exist, they won't be overridden, so e.g. appsettings.json configuration will + /// take precedence. + /// + /// The instance of the app. + /// Configuration for the hosting defaults. + public static OrchardCoreBuilder ConfigureHostingDefaults( + this OrchardCoreBuilder builder, + WebApplicationBuilder webApplicationBuilder, + HostingConfiguration hostingConfiguration = null) + { + hostingConfiguration ??= new HostingConfiguration(); + + // Not using static type references for the names here because those practically never change, but we'd need to + // add project/package references to all the affected projects. + + var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); + + ocSection.GetSection("OrchardCore_Tenants").AddValueIfKeyNotExists("TenantRemovalAllowed", "true"); + + var logLevelSection = webApplicationBuilder.Configuration.GetSection("Logging:LogLevel"); + + if (webApplicationBuilder.Environment.IsDevelopment()) + { + logLevelSection + .AddValueIfKeyNotExists("Default", "Debug") + .AddValueIfKeyNotExists("System", "Information") + .AddValueIfKeyNotExists("Microsoft", "Information"); + + // Orchard Core 1.8 and prior, this can be removed after an Orchard Core upgrade to 2.0. + // OrchardCore_Email_Smtp below is 2.0+. + var oc18SmtpSection = ocSection.GetSection("SmtpSettings"); + + if (oc18SmtpSection["Host"] == null) + { + oc18SmtpSection["Host"] = "127.0.0.1"; + oc18SmtpSection["RequireCredentials"] = "false"; + oc18SmtpSection["Port"] = "25"; + } + + oc18SmtpSection.AddValueIfKeyNotExists("DefaultSender", "sender@example.com"); + + var smtpSection = ocSection.GetSection("OrchardCore_Email_Smtp"); + + if (smtpSection["Host"] == null) + { + smtpSection["Host"] = "127.0.0.1"; + smtpSection["RequireCredentials"] = "false"; + smtpSection["Port"] = "25"; + } + + smtpSection.AddValueIfKeyNotExists("DefaultSender", "sender@example.com"); + } + else + { + logLevelSection + .AddValueIfKeyNotExists("Default", "Warning") + .AddValueIfKeyNotExists("Microsoft.AspNetCore", "Warning"); + } + + if (hostingConfiguration.EnableHealthChecksInProduction && webApplicationBuilder.Environment.IsProduction()) + { + builder.AddTenantFeatures("OrchardCore.HealthChecks"); + } + + builder + .AddDatabaseShellsConfigurationIfAvailable(webApplicationBuilder.Configuration) + .ConfigureSmtpSettings(overrideAdminSettings: false) + .ConfigureSecurityDefaultsWithStaticFiles(allowInlineStyle: true); + + return builder; + } + + /// + /// Lombiq-recommended opinionated default configuration for features of an Orchard Core application hosted in + /// Azure. If any of the configuration values exist, they won't be overridden, so e.g. appsettings.json + /// configuration will take precedence. + /// + /// The instance of the app. + /// Configuration for the hosting defaults. + public static OrchardCoreBuilder ConfigureAzureHostingDefaults( + this OrchardCoreBuilder builder, + WebApplicationBuilder webApplicationBuilder, + AzureHostingConfiguration hostingConfiguration = null) + { + hostingConfiguration ??= new AzureHostingConfiguration(); + + builder.ConfigureHostingDefaults(webApplicationBuilder, hostingConfiguration); + + var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); + + if (webApplicationBuilder.Configuration.IsAzureHosting()) + { + builder + .AddTenantFeatures( + "OrchardCore.DataProtection.Azure", + "Lombiq.Hosting.BuildVersionDisplay") + .DisableResourceDebugMode(); + + if (hostingConfiguration.EnableAzureMediaStorage) + { + // Azure Media Storage and its dependencies. Keep this updated with Orchard upgrades. + builder.AddTenantFeatures( + "OrchardCore.Contents", + "OrchardCore.ContentTypes", + "OrchardCore.Liquid", + "OrchardCore.Media", + "OrchardCore.Media.Azure.Storage", + "OrchardCore.Media.Cache", + "OrchardCore.Settings"); + } + } + + if (webApplicationBuilder.Environment.IsDevelopment()) + { + var dataProtectionSection = ocSection.GetSection("OrchardCore_DataProtection_Azure"); + + dataProtectionSection.AddValueIfKeyNotExists("CreateContainer", "true"); + dataProtectionSection.AddValueIfKeyNotExists("ConnectionString", "UseDevelopmentStorage=true"); + } + + return builder; + } +} + +public class HostingConfiguration +{ + /// + /// Gets or sets a value indicating whether to enable OrchardCore.HealthChecks in the Production environment. + /// + public bool EnableHealthChecksInProduction { get; set; } = true; +} + +public class AzureHostingConfiguration : HostingConfiguration +{ + /// + /// Gets or sets a value indicating whether to enable OrchardCore.Media.Azure.Storage and its + /// dependencies when hosted in Azure. + /// + public bool EnableAzureMediaStorage { get; set; } = true; +} diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs index d986cb16..3e611531 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/OrchardCoreBuilderExtensions.cs @@ -1,6 +1,4 @@ -using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Hosting; using OrchardCore.Email; using OrchardCore.Environment.Shell.Configuration; using OrchardCore.ResourceManagement; @@ -60,146 +58,4 @@ public static OrchardCoreBuilder ConfigureSmtpSettings( public static OrchardCoreBuilder DisableResourceDebugMode(this OrchardCoreBuilder builder) => builder.ConfigureServices((tenantServices, _) => tenantServices.PostConfigure(settings => settings.DebugMode = false)); - - /// - /// Lombiq-recommended opinionated default configuration for features of a standard Orchard Core application. If any - /// of the configuration values exist, they won't be overridden, so e.g. appsettings.json configuration will take - /// precedence. - /// - /// The instance of the app. - /// Configuration for the hosting defaults. - public static OrchardCoreBuilder ConfigureHostingDefaults( - this OrchardCoreBuilder builder, - WebApplicationBuilder webApplicationBuilder, - HostingConfiguration hostingConfiguration = null) - { - hostingConfiguration ??= new HostingConfiguration(); - - // Not using static type references for the names here because those practically never change, but we'd need to - // add project/package references to all the affected projects. - - var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); - - ocSection.GetSection("OrchardCore_Tenants").AddValueIfKeyNotExists("TenantRemovalAllowed", "true"); - - var logLevelSection = webApplicationBuilder.Configuration.GetSection("Logging:LogLevel"); - - if (webApplicationBuilder.Environment.IsDevelopment()) - { - logLevelSection - .AddValueIfKeyNotExists("Default", "Debug") - .AddValueIfKeyNotExists("System", "Information") - .AddValueIfKeyNotExists("Microsoft", "Information"); - - // Orchard Core 1.8 and prior, this can be removed after an Orchard Core upgrade to 2.0. - // OrchardCore_Email_Smtp below is 2.0+. - var oc18SmtpSection = ocSection.GetSection("SmtpSettings"); - - if (oc18SmtpSection["Host"] == null) - { - oc18SmtpSection["Host"] = "127.0.0.1"; - oc18SmtpSection["RequireCredentials"] = "false"; - oc18SmtpSection["Port"] = "25"; - } - - oc18SmtpSection.AddValueIfKeyNotExists("DefaultSender", "sender@example.com"); - - var smtpSection = ocSection.GetSection("OrchardCore_Email_Smtp"); - - if (smtpSection["Host"] == null) - { - smtpSection["Host"] = "127.0.0.1"; - smtpSection["RequireCredentials"] = "false"; - smtpSection["Port"] = "25"; - } - - smtpSection.AddValueIfKeyNotExists("DefaultSender", "sender@example.com"); - } - else - { - logLevelSection - .AddValueIfKeyNotExists("Default", "Warning") - .AddValueIfKeyNotExists("Microsoft.AspNetCore", "Warning"); - } - - if (hostingConfiguration.EnableHealthChecksInProduction && webApplicationBuilder.Environment.IsProduction()) - { - builder.AddTenantFeatures("OrchardCore.HealthChecks"); - } - - builder - .AddDatabaseShellsConfigurationIfAvailable(webApplicationBuilder.Configuration) - .ConfigureSmtpSettings(overrideAdminSettings: false) - .ConfigureSecurityDefaultsWithStaticFiles(allowInlineStyle: true); - - return builder; - } - - /// - /// Lombiq-recommended opinionated default configuration for features of an Orchard Core application hosted in - /// Azure. If any of the configuration values exist, they won't be overridden, so e.g. appsettings.json - /// configuration will take precedence. - /// - /// The instance of the app. - /// Configuration for the hosting defaults. - public static OrchardCoreBuilder ConfigureAzureHostingDefaults( - this OrchardCoreBuilder builder, - WebApplicationBuilder webApplicationBuilder, - AzureHostingConfiguration hostingConfiguration = null) - { - hostingConfiguration ??= new AzureHostingConfiguration(); - - builder.ConfigureHostingDefaults(webApplicationBuilder, hostingConfiguration); - - var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); - - if (webApplicationBuilder.Configuration.IsAzureHosting()) - { - builder - .AddTenantFeatures( - "OrchardCore.DataProtection.Azure", - "Lombiq.Hosting.BuildVersionDisplay") - .DisableResourceDebugMode(); - - if (hostingConfiguration.EnableAzureMediaStorage) - { - // Azure Media Storage and its dependencies. Keep this updated with Orchard upgrades. - builder.AddTenantFeatures( - "OrchardCore.Contents", - "OrchardCore.ContentTypes", - "OrchardCore.Liquid", - "OrchardCore.Media", - "OrchardCore.Media.Azure.Storage", - "OrchardCore.Media.Cache", - "OrchardCore.Settings"); - } - } - - if (webApplicationBuilder.Environment.IsDevelopment()) - { - var dataProtectionSection = ocSection.GetSection("OrchardCore_DataProtection_Azure"); - - dataProtectionSection.AddValueIfKeyNotExists("CreateContainer", "true"); - dataProtectionSection.AddValueIfKeyNotExists("ConnectionString", "UseDevelopmentStorage=true"); - } - - return builder; - } -} - -public class HostingConfiguration -{ - /// - /// Gets or sets a value indicating whether to enable OrchardCore.HealthChecks in the Production environment. - /// - public bool EnableHealthChecksInProduction { get; set; } = true; -} - -public class AzureHostingConfiguration : HostingConfiguration -{ - /// - /// Gets or sets a value indicating whether to enable OrchardCore.Media.Azure.Storage and its - /// dependencies when hosted in Azure. - /// - public bool EnableAzureMediaStorage { get; set; } = true; } From 52bb2cc33750eeba62aea540dd32956fc71171b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 17:13:18 +0200 Subject: [PATCH 10/18] Adding OrchardCore_Media_Azure defaults --- .../HostingDefaultsOrchardCoreBuilderExtensions.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs index 661aa7ce..f6edb9f6 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; @@ -126,6 +126,11 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( dataProtectionSection.AddValueIfKeyNotExists("CreateContainer", "true"); dataProtectionSection.AddValueIfKeyNotExists("ConnectionString", "UseDevelopmentStorage=true"); + + var mediaSection = ocSection.GetSection("OrchardCore_Media_Azure"); + + mediaSection.AddValueIfKeyNotExists("CreateContainer", "true"); + mediaSection.AddValueIfKeyNotExists("ConnectionString", "UseDevelopmentStorage=true"); } return builder; From bb808d243997a1a36d83eedf610b1dbbe720ea61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 17:17:01 +0200 Subject: [PATCH 11/18] Better OrchardCore_Media_Azure defaults --- .../HostingDefaultsOrchardCoreBuilderExtensions.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs index f6edb9f6..1267401d 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs @@ -120,6 +120,11 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( } } + var mediaSection = ocSection.GetSection("OrchardCore_Media_Azure"); + + mediaSection.AddValueIfKeyNotExists("ContainerName", "media"); + mediaSection.AddValueIfKeyNotExists("BasePath", "{{ ShellSettings.Name }}"); + if (webApplicationBuilder.Environment.IsDevelopment()) { var dataProtectionSection = ocSection.GetSection("OrchardCore_DataProtection_Azure"); @@ -127,8 +132,6 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( dataProtectionSection.AddValueIfKeyNotExists("CreateContainer", "true"); dataProtectionSection.AddValueIfKeyNotExists("ConnectionString", "UseDevelopmentStorage=true"); - var mediaSection = ocSection.GetSection("OrchardCore_Media_Azure"); - mediaSection.AddValueIfKeyNotExists("CreateContainer", "true"); mediaSection.AddValueIfKeyNotExists("ConnectionString", "UseDevelopmentStorage=true"); } From 83f6ac79e5b7762466ad54c6c4dbb5781f7a95c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 17:44:42 +0200 Subject: [PATCH 12/18] Adding OrchardCore_Localization_CultureOptions defaults --- .../Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs index 1267401d..076f723d 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs @@ -27,6 +27,8 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( ocSection.GetSection("OrchardCore_Tenants").AddValueIfKeyNotExists("TenantRemovalAllowed", "true"); + ocSection.GetSection("OrchardCore_Localization_CultureOptions").AddValueIfKeyNotExists("IgnoreSystemSettings", "true"); + var logLevelSection = webApplicationBuilder.Configuration.GetSection("Logging:LogLevel"); if (webApplicationBuilder.Environment.IsDevelopment()) From e70a4be91f9ca63466b6e4821a545957a4792783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 18:12:53 +0200 Subject: [PATCH 13/18] Adding OrchardCore_Shells_Database defaults --- .../HostingDefaultsOrchardCoreBuilderExtensions.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs index 076f723d..16519a26 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs @@ -29,6 +29,11 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( ocSection.GetSection("OrchardCore_Localization_CultureOptions").AddValueIfKeyNotExists("IgnoreSystemSettings", "true"); + var shellsDatabaseSection = ocSection.GetSection("OrchardCore_Shells_Database"); + + shellsDatabaseSection.AddValueIfKeyNotExists("DatabaseProvider", "SqlConnection"); + shellsDatabaseSection.AddValueIfKeyNotExists("TablePrefix", "Shells"); + var logLevelSection = webApplicationBuilder.Configuration.GetSection("Logging:LogLevel"); if (webApplicationBuilder.Environment.IsDevelopment()) From 0b66ca4c4b611e77d46961317b8b3f630029022c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 18:15:28 +0200 Subject: [PATCH 14/18] Adding OrchardCore_Tenants defaults --- .../Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs index 16519a26..ccedf84c 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs @@ -34,6 +34,8 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( shellsDatabaseSection.AddValueIfKeyNotExists("DatabaseProvider", "SqlConnection"); shellsDatabaseSection.AddValueIfKeyNotExists("TablePrefix", "Shells"); + ocSection.GetSection("OrchardCore_Tenants").AddValueIfKeyNotExists("TenantRemovalAllowed", "true"); + var logLevelSection = webApplicationBuilder.Configuration.GetSection("Logging:LogLevel"); if (webApplicationBuilder.Environment.IsDevelopment()) From 5b774464fca348d3266dedc7561285a24c19fdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 19:14:10 +0200 Subject: [PATCH 15/18] Adding OrchardCore_Elasticsearch defaults --- ...ingDefaultsOrchardCoreBuilderExtensions.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs index ccedf84c..32d59234 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs @@ -37,6 +37,7 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( ocSection.GetSection("OrchardCore_Tenants").AddValueIfKeyNotExists("TenantRemovalAllowed", "true"); var logLevelSection = webApplicationBuilder.Configuration.GetSection("Logging:LogLevel"); + var elasticSearchSection = ocSection.GetSection("OrchardCore_Elasticsearch"); if (webApplicationBuilder.Environment.IsDevelopment()) { @@ -68,12 +69,31 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( } smtpSection.AddValueIfKeyNotExists("DefaultSender", "sender@example.com"); + + if (elasticSearchSection["Url"] == null) + { + elasticSearchSection["ConnectionType"] = "SingleNodeConnectionPool"; + elasticSearchSection["Url"] = "http://localhost"; + elasticSearchSection["Ports:0"] = "9200"; + elasticSearchSection["Username"] = "admin"; + elasticSearchSection["Password"] = "admin"; + } } else { logLevelSection .AddValueIfKeyNotExists("Default", "Warning") .AddValueIfKeyNotExists("Microsoft.AspNetCore", "Warning"); + + // Elastic Cloud configuration if none is provided. The Url and Password are still needed. + if (elasticSearchSection["ConnectionType"] == null && + elasticSearchSection["Ports"] == null && + elasticSearchSection["Username"] == null) + { + elasticSearchSection["ConnectionType"] = "CloudConnectionPool"; + elasticSearchSection["Ports:0"] = "9243"; + elasticSearchSection["Username"] = "elastic"; + } } if (hostingConfiguration.EnableHealthChecksInProduction && webApplicationBuilder.Environment.IsProduction()) From 327f501f06dfecfe09004af9c0f70bcb9536d577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 30 Jul 2024 19:26:38 +0200 Subject: [PATCH 16/18] Adding DatabaseProvider and IsAzureHosting defaults --- ...rationExtensions.cs => AzureConfigurationExtensions.cs} | 6 ++++-- .../HostingDefaultsOrchardCoreBuilderExtensions.cs | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) rename Lombiq.HelpfulLibraries.Common/Extensions/{ConfigurationExtensions.cs => AzureConfigurationExtensions.cs} (62%) diff --git a/Lombiq.HelpfulLibraries.Common/Extensions/ConfigurationExtensions.cs b/Lombiq.HelpfulLibraries.Common/Extensions/AzureConfigurationExtensions.cs similarity index 62% rename from Lombiq.HelpfulLibraries.Common/Extensions/ConfigurationExtensions.cs rename to Lombiq.HelpfulLibraries.Common/Extensions/AzureConfigurationExtensions.cs index 0ab3cddf..9a3fe00f 100644 --- a/Lombiq.HelpfulLibraries.Common/Extensions/ConfigurationExtensions.cs +++ b/Lombiq.HelpfulLibraries.Common/Extensions/AzureConfigurationExtensions.cs @@ -1,12 +1,14 @@ namespace Microsoft.Extensions.Configuration; -public static class ConfigurationExtensions +public static class AzureConfigurationExtensions { + public const string IsAzureHostingKey = "IsAzureHosting"; + /// /// Retrieves a value indicating whether the OrchardCore:IsAzureHosting configuration key is set to . /// public static bool IsAzureHosting( this IConfiguration configuration) => - configuration.GetValue("OrchardCore:IsAzureHosting"); + configuration.GetValue("OrchardCore:" + IsAzureHostingKey); } diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs index 32d59234..b5e15415 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs @@ -85,6 +85,8 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( .AddValueIfKeyNotExists("Default", "Warning") .AddValueIfKeyNotExists("Microsoft.AspNetCore", "Warning"); + ocSection.AddValueIfKeyNotExists("DatabaseProvider", "SqlConnection"); + // Elastic Cloud configuration if none is provided. The Url and Password are still needed. if (elasticSearchSection["ConnectionType"] == null && elasticSearchSection["Ports"] == null && @@ -127,6 +129,11 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( var ocSection = webApplicationBuilder.Configuration.GetSection("OrchardCore"); + if (!webApplicationBuilder.Environment.IsDevelopment()) + { + ocSection.AddValueIfKeyNotExists(AzureConfigurationExtensions.IsAzureHostingKey, "true"); + } + if (webApplicationBuilder.Configuration.IsAzureHosting()) { builder From a3a6f3c5a1182e79c176bd1c3d87e9a69193bbc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Mon, 5 Aug 2024 18:46:28 +0200 Subject: [PATCH 17/18] Better HostingConfiguration property names --- .../HostingDefaultsOrchardCoreBuilderExtensions.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs index b5e15415..256a77e2 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs @@ -98,7 +98,7 @@ public static OrchardCoreBuilder ConfigureHostingDefaults( } } - if (hostingConfiguration.EnableHealthChecksInProduction && webApplicationBuilder.Environment.IsProduction()) + if (hostingConfiguration.AlwaysEnableHealthChecksInProduction && webApplicationBuilder.Environment.IsProduction()) { builder.AddTenantFeatures("OrchardCore.HealthChecks"); } @@ -142,7 +142,7 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( "Lombiq.Hosting.BuildVersionDisplay") .DisableResourceDebugMode(); - if (hostingConfiguration.EnableAzureMediaStorage) + if (hostingConfiguration.AlwaysEnableAzureMediaStorage) { // Azure Media Storage and its dependencies. Keep this updated with Orchard upgrades. builder.AddTenantFeatures( @@ -181,7 +181,7 @@ public class HostingConfiguration /// /// Gets or sets a value indicating whether to enable OrchardCore.HealthChecks in the Production environment. /// - public bool EnableHealthChecksInProduction { get; set; } = true; + public bool AlwaysEnableHealthChecksInProduction { get; set; } = true; } public class AzureHostingConfiguration : HostingConfiguration @@ -190,5 +190,5 @@ public class AzureHostingConfiguration : HostingConfiguration /// Gets or sets a value indicating whether to enable OrchardCore.Media.Azure.Storage and its /// dependencies when hosted in Azure. /// - public bool EnableAzureMediaStorage { get; set; } = true; + public bool AlwaysEnableAzureMediaStorage { get; set; } = true; } From fda03ab71439ecb338b51787d9f3e3dfc44359fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Mon, 5 Aug 2024 19:09:57 +0200 Subject: [PATCH 18/18] Docs --- .../HostingDefaultsOrchardCoreBuilderExtensions.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs index 256a77e2..3431ee7b 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Environment/HostingDefaultsOrchardCoreBuilderExtensions.cs @@ -179,7 +179,8 @@ public static OrchardCoreBuilder ConfigureAzureHostingDefaults( public class HostingConfiguration { /// - /// Gets or sets a value indicating whether to enable OrchardCore.HealthChecks in the Production environment. + /// Gets or sets a value indicating whether to always enable OrchardCore.HealthChecks and its dependencies in + /// the Production environment, for all tenants, without the ability to turn them off. /// public bool AlwaysEnableHealthChecksInProduction { get; set; } = true; } @@ -187,8 +188,8 @@ public class HostingConfiguration public class AzureHostingConfiguration : HostingConfiguration { /// - /// Gets or sets a value indicating whether to enable OrchardCore.Media.Azure.Storage and its - /// dependencies when hosted in Azure. + /// Gets or sets a value indicating whether to always enable OrchardCore.Media.Azure.Storage and its + /// dependencies when hosted in Azure, for all tenants, without the ability to turn them off. /// public bool AlwaysEnableAzureMediaStorage { get; set; } = true; }