From 6417948a5852296139a3debdc0b5b484c7f9b896 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 4 Nov 2024 12:27:47 +0100 Subject: [PATCH] #17391 (#17413) Fixes issue with the delivery api can find unpublished content --- src/Umbraco.Core/Routing/NewDefaultUrlProvider.cs | 2 +- src/Umbraco.Core/Services/DocumentUrlService.cs | 11 ++++++++--- .../DocumentCache.cs | 15 ++++++++------- .../Services/DocumentCacheService.cs | 8 +++++++- .../DocumentHybridCacheTests.cs | 13 +++++++++++++ 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Core/Routing/NewDefaultUrlProvider.cs b/src/Umbraco.Core/Routing/NewDefaultUrlProvider.cs index 4e636a3f9e..f7eeb1a1b4 100644 --- a/src/Umbraco.Core/Routing/NewDefaultUrlProvider.cs +++ b/src/Umbraco.Core/Routing/NewDefaultUrlProvider.cs @@ -177,7 +177,7 @@ public class NewDefaultUrlProvider : IUrlProvider UrlMode mode, string? culture) { - if (string.IsNullOrWhiteSpace(route)) + if (string.IsNullOrWhiteSpace(route) || route.Equals("#")) { if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { diff --git a/src/Umbraco.Core/Services/DocumentUrlService.cs b/src/Umbraco.Core/Services/DocumentUrlService.cs index 6e251751f6..5148720a56 100644 --- a/src/Umbraco.Core/Services/DocumentUrlService.cs +++ b/src/Umbraco.Core/Services/DocumentUrlService.cs @@ -426,21 +426,26 @@ public class DocumentUrlService : IDocumentUrlService private bool IsContentPublished(Guid contentKey, string culture) => _publishStatusQueryService.IsDocumentPublished(contentKey, culture); - public string GetLegacyRouteFormat(Guid docuemntKey, string? culture, bool isDraft) + public string GetLegacyRouteFormat(Guid documentKey, string? culture, bool isDraft) { - Attempt documentIdAttempt = _idKeyMap.GetIdForKey(docuemntKey, UmbracoObjectTypes.Document); + Attempt documentIdAttempt = _idKeyMap.GetIdForKey(documentKey, UmbracoObjectTypes.Document); if(documentIdAttempt.Success is false) { return "#"; } - if (_documentNavigationQueryService.TryGetAncestorsOrSelfKeys(docuemntKey, + if (_documentNavigationQueryService.TryGetAncestorsOrSelfKeys(documentKey, out IEnumerable ancestorsOrSelfKeys) is false) { return "#"; } + if(isDraft is false && culture != null && _publishStatusQueryService.IsDocumentPublished(documentKey, culture) is false) + { + return "#"; + } + var cultureOrDefault = string.IsNullOrWhiteSpace(culture) is false ? culture : _languageService.GetDefaultIsoCodeAsync().GetAwaiter().GetResult(); Guid[] ancestorsOrSelfKeysArray = ancestorsOrSelfKeys as Guid[] ?? ancestorsOrSelfKeys.ToArray(); diff --git a/src/Umbraco.PublishedCache.HybridCache/DocumentCache.cs b/src/Umbraco.PublishedCache.HybridCache/DocumentCache.cs index 9be78a9ea2..aab97f9b3c 100644 --- a/src/Umbraco.PublishedCache.HybridCache/DocumentCache.cs +++ b/src/Umbraco.PublishedCache.HybridCache/DocumentCache.cs @@ -3,9 +3,9 @@ using Umbraco.Cms.Core; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Services.Navigation; -using Umbraco.Cms.Infrastructure.HybridCache.Services; using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.HybridCache; @@ -95,7 +95,7 @@ public sealed class DocumentCache : IPublishedContentCache public IEnumerable GetByContentType(IPublishedContentType contentType) => _documentCacheService.GetByContentType(contentType); - [Obsolete("Use IDocumentUrlService.GetDocumentKeyByRoute instead, scheduled for removal in v17")] + [Obsolete("Use IPublishedUrlProvider.GetUrl instead, scheduled for removal in v17")] public IPublishedContent? GetByRoute(bool preview, string route, bool? hideTopLevelNode = null, string? culture = null) { IDocumentUrlService documentUrlService = StaticServiceProvider.Instance.GetRequiredService(); @@ -103,7 +103,7 @@ public sealed class DocumentCache : IPublishedContentCache return key is not null ? GetById(preview, key.Value) : null; } - [Obsolete("Use IDocumentUrlService.GetDocumentKeyByRoute instead, scheduled for removal in v17")] + [Obsolete("Use IPublishedUrlProvider.GetUrl instead, scheduled for removal in v17")] public IPublishedContent? GetByRoute(string route, bool? hideTopLevelNode = null, string? culture = null) { IDocumentUrlService documentUrlService = StaticServiceProvider.Instance.GetRequiredService(); @@ -111,14 +111,15 @@ public sealed class DocumentCache : IPublishedContentCache return key is not null ? GetById(key.Value) : null; } - [Obsolete("Use IDocumentUrlService.GetDocumentKeyByRoute instead, scheduled for removal in v17")] + [Obsolete("Use IPublishedUrlProvider.GetUrl instead, scheduled for removal in v17")] public string? GetRouteById(bool preview, int contentId, string? culture = null) { - IDocumentUrlService documentUrlService = StaticServiceProvider.Instance.GetRequiredService(); + IPublishedUrlProvider publishedUrlProvider = StaticServiceProvider.Instance.GetRequiredService(); IPublishedContent? content = GetById(preview, contentId); - return content is not null ? documentUrlService.GetLegacyRouteFormat(content.Key, culture, preview) : null; + + return content is not null ? publishedUrlProvider.GetUrl(content, UrlMode.Relative, culture) : null; } - [Obsolete("Use IDocumentUrlService.GetDocumentKeyByRoute instead, scheduled for removal in v17")] + [Obsolete("Use IPublishedUrlProvider.GetUrl instead, scheduled for removal in v17")] public string? GetRouteById(int contentId, string? culture = null) => GetRouteById(false, contentId, culture); } diff --git a/src/Umbraco.PublishedCache.HybridCache/Services/DocumentCacheService.cs b/src/Umbraco.PublishedCache.HybridCache/Services/DocumentCacheService.cs index 135d2f99dd..dc7885ee38 100644 --- a/src/Umbraco.PublishedCache.HybridCache/Services/DocumentCacheService.cs +++ b/src/Umbraco.PublishedCache.HybridCache/Services/DocumentCacheService.cs @@ -270,11 +270,17 @@ internal sealed class DocumentCacheService : IDocumentCacheService await _databaseCacheRepository.RefreshContentAsync(draftCacheNode, content.PublishedState); - if (content.PublishedState == PublishedState.Publishing) + if (content.PublishedState == PublishedState.Publishing || content.PublishedState == PublishedState.Unpublishing) { var publishedCacheNode = _cacheNodeFactory.ToContentCacheNode(content, false); await _databaseCacheRepository.RefreshContentAsync(publishedCacheNode, content.PublishedState); + + if (content.PublishedState == PublishedState.Unpublishing) + { + await _hybridCache.RemoveAsync(GetCacheKey(publishedCacheNode.Key, false)); + } + } scope.Complete(); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/DocumentHybridCacheTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/DocumentHybridCacheTests.cs index 34660435a7..c757001136 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/DocumentHybridCacheTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/DocumentHybridCacheTests.cs @@ -83,6 +83,19 @@ public class DocumentHybridCacheTests : UmbracoIntegrationTestWithContentEditing Assert.IsFalse(textPage.IsPublished()); } + [Test] + public async Task Cannot_get_unpublished_content() + { + // Arrange + var unpublishAttempt = await ContentPublishingService.UnpublishAsync(PublishedTextPage.Key.Value, null, Constants.Security.SuperUserKey); + + //Act + var textPage = await PublishedContentHybridCache.GetByIdAsync(PublishedTextPageId, false); + + // Assert + Assert.IsNull(textPage); + } + [Test] public async Task Can_Get_Draft_Of_Published_Content_By_Key() {