diff --git a/src/Umbraco.Cms.Persistence.SqlServer/Services/SqlServerDistributedLockingMechanism.cs b/src/Umbraco.Cms.Persistence.SqlServer/Services/SqlServerDistributedLockingMechanism.cs index 12a0afea47..358eae2e38 100644 --- a/src/Umbraco.Cms.Persistence.SqlServer/Services/SqlServerDistributedLockingMechanism.cs +++ b/src/Umbraco.Cms.Persistence.SqlServer/Services/SqlServerDistributedLockingMechanism.cs @@ -39,7 +39,7 @@ public class SqlServerDistributedLockingMechanism : IDistributedLockingMechanism /// public bool Enabled => _connectionStrings.CurrentValue.IsConnectionStringConfigured() && - _connectionStrings.CurrentValue.ProviderName == Constants.ProviderName; + string.Equals(_connectionStrings.CurrentValue.ProviderName,Constants.ProviderName, StringComparison.InvariantCultureIgnoreCase); /// public IDistributedLock ReadLock(int lockId, TimeSpan? obtainLockTimeout = null) diff --git a/src/Umbraco.Cms.Persistence.Sqlite/Constants.cs b/src/Umbraco.Cms.Persistence.Sqlite/Constants.cs index 63f0d8f9fe..5c10f46828 100644 --- a/src/Umbraco.Cms.Persistence.Sqlite/Constants.cs +++ b/src/Umbraco.Cms.Persistence.Sqlite/Constants.cs @@ -8,5 +8,8 @@ public static class Constants /// /// SQLite provider name. /// - public const string ProviderName = "Microsoft.Data.SQLite"; + public const string ProviderName = "Microsoft.Data.Sqlite"; + + [Obsolete("This will be removed in Umbraco 12. Use Constants.ProviderName instead")] + public const string ProviderNameLegacy = "Microsoft.Data.SQLite"; } diff --git a/src/Umbraco.Cms.Persistence.Sqlite/Services/SqliteDistributedLockingMechanism.cs b/src/Umbraco.Cms.Persistence.Sqlite/Services/SqliteDistributedLockingMechanism.cs index c704bb8272..a4a31416fa 100644 --- a/src/Umbraco.Cms.Persistence.Sqlite/Services/SqliteDistributedLockingMechanism.cs +++ b/src/Umbraco.Cms.Persistence.Sqlite/Services/SqliteDistributedLockingMechanism.cs @@ -35,7 +35,7 @@ public class SqliteDistributedLockingMechanism : IDistributedLockingMechanism /// public bool Enabled => _connectionStrings.CurrentValue.IsConnectionStringConfigured() && - _connectionStrings.CurrentValue.ProviderName == Constants.ProviderName; + string.Equals(_connectionStrings.CurrentValue.ProviderName, Constants.ProviderName, StringComparison.InvariantCultureIgnoreCase); // With journal_mode=wal we can always read a snapshot. public IDistributedLock ReadLock(int lockId, TimeSpan? obtainLockTimeout = null) diff --git a/src/Umbraco.Cms.Persistence.Sqlite/UmbracoBuilderExtensions.cs b/src/Umbraco.Cms.Persistence.Sqlite/UmbracoBuilderExtensions.cs index b617831b86..a4b90881b1 100644 --- a/src/Umbraco.Cms.Persistence.Sqlite/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Cms.Persistence.Sqlite/UmbracoBuilderExtensions.cs @@ -46,11 +46,14 @@ public static class UmbracoBuilderExtensions DbProviderFactories.UnregisterFactory(Constants.ProviderName); DbProviderFactories.RegisterFactory(Constants.ProviderName, SqliteFactory.Instance); + DbProviderFactories.UnregisterFactory(Constants.ProviderNameLegacy); + DbProviderFactories.RegisterFactory(Constants.ProviderNameLegacy, Microsoft.Data.Sqlite.SqliteFactory.Instance); + // Prevent accidental creation of SQLite database files builder.Services.PostConfigureAll(options => { // Skip empty connection string and other providers - if (!options.IsConnectionStringConfigured() || options.ProviderName != Constants.ProviderName) + if (!options.IsConnectionStringConfigured() || (options.ProviderName != Constants.ProviderName && options.ProviderName != Constants.ProviderNameLegacy)) { return; } diff --git a/src/Umbraco.Core/Configuration/Models/ModelsBuilderSettings.cs b/src/Umbraco.Core/Configuration/Models/ModelsBuilderSettings.cs index c791ec6168..0e7e1812c6 100644 --- a/src/Umbraco.Core/Configuration/Models/ModelsBuilderSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/ModelsBuilderSettings.cs @@ -50,11 +50,11 @@ public class ModelsBuilderSettings } return _flagOutOfDateModels; - } - - set =>_flagOutOfDateModels = value; } + set => _flagOutOfDateModels = value; + } + /// /// Gets or sets a value for the models directory. diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs index 3c05e56ac6..94134ab0d1 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs @@ -103,6 +103,8 @@ public static partial class UmbracoBuilderExtensions builder.Services.AddSingleton(f => f.GetRequiredService()); builder.Services.AddSingleton(); + + builder.Services.AddSingleton(); builder.Services.AddSingleton(f => f.GetRequiredService()); builder.Services.AddSingleton(); diff --git a/src/Umbraco.Infrastructure/HostedServices/ReportSiteTask.cs b/src/Umbraco.Infrastructure/HostedServices/ReportSiteTask.cs index cf209109fc..bd69c7857c 100644 --- a/src/Umbraco.Infrastructure/HostedServices/ReportSiteTask.cs +++ b/src/Umbraco.Infrastructure/HostedServices/ReportSiteTask.cs @@ -85,7 +85,8 @@ public class ReportSiteTask : RecurringHostedServiceBase using (var request = new HttpRequestMessage(HttpMethod.Post, "installs/")) { - request.Content = new StringContent(JsonConvert.SerializeObject(telemetryReportData), Encoding.UTF8, "application/json"); + request.Content = new StringContent(JsonConvert.SerializeObject(telemetryReportData), Encoding.UTF8, + "application/json"); // Make a HTTP Post to telemetry service // https://telemetry.umbraco.com/installs/ diff --git a/src/Umbraco.Infrastructure/Persistence/DatabaseProviderMetadataExtensions.cs b/src/Umbraco.Infrastructure/Persistence/DatabaseProviderMetadataExtensions.cs index d0ad59fbb8..1ea941932e 100644 --- a/src/Umbraco.Infrastructure/Persistence/DatabaseProviderMetadataExtensions.cs +++ b/src/Umbraco.Infrastructure/Persistence/DatabaseProviderMetadataExtensions.cs @@ -27,7 +27,7 @@ public static class DatabaseProviderMetadataExtensions /// true if a database can be created for the specified provider name; otherwise, false. /// public static bool CanForceCreateDatabase(this IEnumerable databaseProviderMetadata, string? providerName) - => databaseProviderMetadata.FirstOrDefault(x => x.ProviderName == providerName)?.ForceCreateDatabase == true; + => databaseProviderMetadata.FirstOrDefault(x => string.Equals(x.ProviderName, providerName, StringComparison.InvariantCultureIgnoreCase))?.ForceCreateDatabase == true; /// /// Generates the connection string. diff --git a/src/Umbraco.Infrastructure/Persistence/DbProviderFactoryCreator.cs b/src/Umbraco.Infrastructure/Persistence/DbProviderFactoryCreator.cs index 05b8a41f1e..acb90da5b2 100644 --- a/src/Umbraco.Infrastructure/Persistence/DbProviderFactoryCreator.cs +++ b/src/Umbraco.Infrastructure/Persistence/DbProviderFactoryCreator.cs @@ -40,10 +40,10 @@ public class DbProviderFactoryCreator : IDbProviderFactoryCreator { _getFactory = getFactory; _providerSpecificInterceptors = providerSpecificInterceptors; - _databaseCreators = databaseCreators.ToDictionary(x => x.ProviderName); - _syntaxProviders = syntaxProviders.ToDictionary(x => x.ProviderName); - _bulkSqlInsertProviders = bulkSqlInsertProviders.ToDictionary(x => x.ProviderName); - _providerSpecificMapperFactories = providerSpecificMapperFactories.ToDictionary(x => x.ProviderName); + _databaseCreators = databaseCreators.ToDictionary(x => x.ProviderName, StringComparer.InvariantCultureIgnoreCase); + _syntaxProviders = syntaxProviders.ToDictionary(x => x.ProviderName, StringComparer.InvariantCultureIgnoreCase); + _bulkSqlInsertProviders = bulkSqlInsertProviders.ToDictionary(x => x.ProviderName, StringComparer.InvariantCultureIgnoreCase); + _providerSpecificMapperFactories = providerSpecificMapperFactories.ToDictionary(x => x.ProviderName, StringComparer.InvariantCultureIgnoreCase); } public DbProviderFactory? CreateFactory(string? providerName) @@ -98,5 +98,5 @@ public class DbProviderFactoryCreator : IDbProviderFactoryCreator } public IEnumerable GetProviderSpecificInterceptors(string providerName) - => _providerSpecificInterceptors.Where(x => x.ProviderName == providerName); + => _providerSpecificInterceptors.Where(x => x.ProviderName.Equals(providerName, StringComparison.InvariantCultureIgnoreCase)); } diff --git a/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs b/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs index e96856d0b8..f9ce2837e0 100644 --- a/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs +++ b/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs @@ -11,6 +11,7 @@ internal class FileSystemMainDomLock : IMainDomLock { private readonly CancellationTokenSource _cancellationTokenSource = new(); private readonly IHostingEnvironment _hostingEnvironment; + private readonly IHostingEnvironment _hostingEnvironment; private readonly IOptionsMonitor _globalSettings; private readonly string _lockFilePath; private readonly ILogger _logger; diff --git a/src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs b/src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs index 31249daa67..9431af4eb9 100644 --- a/src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs +++ b/src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs @@ -10,6 +10,9 @@ using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Infrastructure.Persistence; using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; +using Umbraco.Cms.Core.DistributedLocking; +using Umbraco.Cms.Core.Scoping; +using Umbraco.Cms.Web.Common.DependencyInjection; using CoreDebugSettings = Umbraco.Cms.Core.Configuration.Models.CoreDebugSettings; #if DEBUG_SCOPES diff --git a/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs index c1f9dbac4e..bc19688427 100644 --- a/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/OutgoingEditorModelEventAttribute.cs @@ -27,7 +27,7 @@ internal sealed class OutgoingEditorModelEventAttribute : TypeFilterAttribute private class OutgoingEditorModelEventFilter : IActionFilter { - private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor; + private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;private readonly IUmbracoMapper _mapper; private readonly IEventAggregator _eventAggregator; private readonly IUmbracoMapper _mapper; private readonly IUmbracoContextAccessor _umbracoContextAccessor; @@ -92,7 +92,8 @@ internal sealed class OutgoingEditorModelEventAttribute : TypeFilterAttribute case ContentItemDisplay content: _eventAggregator.Publish(new SendingContentNotification(content, umbracoContext)); break; - case ContentItemDisplayWithSchedule contentWithSchedule: + + case ContentItemDisplayWithSchedule contentWithSchedule: // This is a bit weird, since ContentItemDisplayWithSchedule was introduced later, // the SendingContentNotification only accepts ContentItemDisplay, // which means we have to map it to this before sending the notification. @@ -112,27 +113,27 @@ internal sealed class OutgoingEditorModelEventAttribute : TypeFilterAttribute _mapper.Map(display, contentWithSchedule, mapperContext => mapperContext.Items[nameof(contentWithSchedule.Variants)] = contentWithSchedule.Variants); break; case MediaItemDisplay media: - _eventAggregator.Publish(new SendingMediaNotification(media, umbracoContext)); - break; - case MemberDisplay member: - _eventAggregator.Publish(new SendingMemberNotification(member, umbracoContext)); - break; - case UserDisplay user: - _eventAggregator.Publish(new SendingUserNotification(user, umbracoContext)); - break; - case IEnumerable> dashboards: - _eventAggregator.Publish(new SendingDashboardsNotification(dashboards, umbracoContext)); - break; - case IEnumerable allowedChildren: - // Changing the Enumerable will generate a new instance, so we need to update the context result with the new content - var notification = new SendingAllowedChildrenNotification(allowedChildren, umbracoContext); - _eventAggregator.Publish(notification); - context.Result = new ObjectResult(notification.Children); - break; + _eventAggregator.Publish(new SendingMediaNotification(media, umbracoContext)); + break; + case MemberDisplay member: + _eventAggregator.Publish(new SendingMemberNotification(member, umbracoContext)); + break; + case UserDisplay user: + _eventAggregator.Publish(new SendingUserNotification(user, umbracoContext)); + break; + case IEnumerable> dashboards: + _eventAggregator.Publish(new SendingDashboardsNotification(dashboards, umbracoContext)); + break; + case IEnumerable allowedChildren: + // Changing the Enumerable will generate a new instance, so we need to update the context result with the new content + var notification = new SendingAllowedChildrenNotification(allowedChildren, umbracoContext); + _eventAggregator.Publish(notification); + context.Result = new ObjectResult(notification.Children); + break; + } } } } - } public void OnActionExecuting(ActionExecutingContext context) { diff --git a/src/Umbraco.Web.Website/Routing/PublicAccessRequestHandler.cs b/src/Umbraco.Web.Website/Routing/PublicAccessRequestHandler.cs index 230dcaefe5..a33ac7bca2 100644 --- a/src/Umbraco.Web.Website/Routing/PublicAccessRequestHandler.cs +++ b/src/Umbraco.Web.Website/Routing/PublicAccessRequestHandler.cs @@ -84,15 +84,25 @@ public class PublicAccessRequestHandler : IPublicAccessRequestHandler switch (publicAccessStatus) { case PublicAccessStatus.NotLoggedIn: - _logger.LogDebug("EnsurePublishedContentAccess: Not logged in, redirect to login page"); - routeValues = await SetPublishedContentAsOtherPageAsync( - httpContext, routeValues.PublishedRequest, publicAccessAttempt.Result!.LoginNodeId); + // redirect if this is not the login page + if (publicAccessAttempt.Result!.LoginNodeId != publishedContent.Id) + { + _logger.LogDebug("EnsurePublishedContentAccess: Not logged in, redirect to login page"); + routeValues = await SetPublishedContentAsOtherPageAsync( + httpContext, routeValues.PublishedRequest, publicAccessAttempt.Result!.LoginNodeId); + } + break; case PublicAccessStatus.AccessDenied: - _logger.LogDebug( - "EnsurePublishedContentAccess: Current member has not access, redirect to error page"); - routeValues = await SetPublishedContentAsOtherPageAsync( - httpContext, routeValues.PublishedRequest, publicAccessAttempt.Result!.NoAccessNodeId); + // Redirect if this is not the access denied page + if (publicAccessAttempt.Result!.NoAccessNodeId != publishedContent.Id) + { + _logger.LogDebug( + "EnsurePublishedContentAccess: Current member has not access, redirect to error page"); + routeValues = await SetPublishedContentAsOtherPageAsync( + httpContext, routeValues.PublishedRequest, publicAccessAttempt.Result!.NoAccessNodeId); + } + break; case PublicAccessStatus.LockedOut: _logger.LogDebug("Current member is locked out, redirect to error page"); diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Scoping/ScopeUnitTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Scoping/ScopeUnitTests.cs index 648b45bb28..77eba6533f 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Scoping/ScopeUnitTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Scoping/ScopeUnitTests.cs @@ -592,10 +592,11 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Scoping using (var scope = scopeProvider.CreateScope()) { - Assert.AreEqual(0, scope.Depth); + Assert.AreEqual(0,scope.Depth); } } + [Test] public void Depth_WhenChildScope_ReturnsDepth() {