Respect user start nodes in GetPagedChildren (used in List View) (#16722)

This commit is contained in:
Elitsa Marinovska
2024-07-02 10:55:03 +03:00
committed by GitHub
parent d8b4361936
commit ef01c27fad

View File

@@ -1,16 +1,11 @@
using System.Collections.Concurrent;
using System.Dynamic; using System.Dynamic;
using System.Globalization; using System.Globalization;
using System.IO;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using System.Security.Cryptography;
using Examine.Search;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Umbraco.Cms.Core; using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.DependencyInjection;
@@ -21,7 +16,6 @@ using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Models.TemplateQuery; using Umbraco.Cms.Core.Models.TemplateQuery;
using Umbraco.Cms.Core.Persistence;
using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Core.Routing;
using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Security;
@@ -718,15 +712,15 @@ public class EntityController : UmbracoAuthorizedJsonController
{ {
//TODO: Need to check for Object types that support hierarchy here, some might not. //TODO: Need to check for Object types that support hierarchy here, some might not.
var startNodes = GetStartNodes(type); var startNodeIds = GetStartNodeIds(type);
var ignoreUserStartNodes = IsDataTypeIgnoringUserStartNodes(dataTypeKey); var ignoreUserStartNodes = IsDataTypeIgnoringUserStartNodes(dataTypeKey);
// root is special: we reduce it to start nodes if the user's start node is not the default, then we need to return their start nodes // root is special: we reduce it to start nodes if the user's start node is not the default, then we need to return their start nodes
if (id == Constants.System.Root && startNodes.Length > 0 && if (id == Constants.System.Root && startNodeIds.Length > 0 &&
startNodes.Contains(Constants.System.Root) == false && !ignoreUserStartNodes) startNodeIds.Contains(Constants.System.Root) == false && !ignoreUserStartNodes)
{ {
IEntitySlim[] nodes = _entityService.GetAll(objectType.Value, startNodes).ToArray(); IEntitySlim[] nodes = _entityService.GetAll(objectType.Value, startNodeIds).ToArray();
if (nodes.Length == 0) if (nodes.Length == 0)
{ {
return Enumerable.Empty<EntityBasic>(); return Enumerable.Empty<EntityBasic>();
@@ -858,13 +852,14 @@ public class EntityController : UmbracoAuthorizedJsonController
{ {
IEnumerable<IEntitySlim> entities; IEnumerable<IEntitySlim> entities;
var startNodes = GetStartNodes(type); var startNodeIds = GetStartNodeIds(type);
var startNodePaths = GetStartNodePaths(type);
var ignoreUserStartNodes = IsDataTypeIgnoringUserStartNodes(dataTypeKey); var ignoreUserStartNodes = IsDataTypeIgnoringUserStartNodes(dataTypeKey);
// root is special: we reduce it to start nodes if the user's start node is not the default, then we need to return their start nodes // root is special: we reduce it to start nodes if the user's start node is not the default, then we need to return their start nodes
if (id == Constants.System.Root && startNodes.Length > 0 && if (id == Constants.System.Root && startNodeIds.Length > 0 &&
startNodes.Contains(Constants.System.Root) == false && !ignoreUserStartNodes) startNodeIds.Contains(Constants.System.Root) == false && !ignoreUserStartNodes)
{ {
return new PagedResult<EntityBasic>(0, 0, 0); return new PagedResult<EntityBasic>(0, 0, 0);
} }
@@ -896,22 +891,28 @@ public class EntityController : UmbracoAuthorizedJsonController
var culture = ClientCulture(); var culture = ClientCulture();
var pagedResult = new PagedResult<EntityBasic>(totalRecords, pageNumber, pageSize) var pagedResult = new PagedResult<EntityBasic>(totalRecords, pageNumber, pageSize)
{ {
Items = entities.Select(source => Items = entities
{ // Filtering out child nodes after getting a paged result is an active choice here, even though the pagination might get off.
EntityBasic? target = _umbracoMapper.Map<IEntitySlim, EntityBasic>(source, context => // This has been the case with this functionality in Umbraco for a long time.
.Where(entity => ignoreUserStartNodes ||
(ContentPermissions.IsInBranchOfStartNode(entity.Path, startNodeIds, startNodePaths, out var hasPathAccess) &&
hasPathAccess))
.Select(source =>
{ {
context.SetCulture(culture); EntityBasic? target = _umbracoMapper.Map<IEntitySlim, EntityBasic>(source, context =>
context.SetCulture(culture); {
}); context.SetCulture(culture);
context.SetCulture(culture);
});
if (target is not null) if (target is not null)
{ {
//TODO: Why is this here and not in the mapping? //TODO: Why is this here and not in the mapping?
target.AdditionalData["hasChildren"] = source.HasChildren; target.AdditionalData["hasChildren"] = source.HasChildren;
} }
return target; return target;
}).WhereNotNull() }).WhereNotNull()
}; };
return pagedResult; return pagedResult;
@@ -931,7 +932,7 @@ public class EntityController : UmbracoAuthorizedJsonController
} }
} }
private int[] GetStartNodes(UmbracoEntityTypes type) private int[] GetStartNodeIds(UmbracoEntityTypes type)
{ {
switch (type) switch (type)
{ {
@@ -946,6 +947,21 @@ public class EntityController : UmbracoAuthorizedJsonController
} }
} }
private string[] GetStartNodePaths(UmbracoEntityTypes type)
{
switch (type)
{
case UmbracoEntityTypes.Document:
return _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.GetContentStartNodePaths(
_entityService, _appCaches) ?? Array.Empty<string>();
case UmbracoEntityTypes.Media:
return _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.GetMediaStartNodePaths(
_entityService, _appCaches) ?? Array.Empty<string>();
default:
return Array.Empty<string>();
}
}
public ActionResult<PagedResult<EntityBasic>> GetPagedDescendants( public ActionResult<PagedResult<EntityBasic>> GetPagedDescendants(
int id, int id,
UmbracoEntityTypes type, UmbracoEntityTypes type,
@@ -979,7 +995,7 @@ public class EntityController : UmbracoAuthorizedJsonController
{ {
// root is special: we reduce it to start nodes // root is special: we reduce it to start nodes
var aids = GetStartNodes(type); var aids = GetStartNodeIds(type);
var ignoreUserStartNodes = IsDataTypeIgnoringUserStartNodes(dataTypeKey); var ignoreUserStartNodes = IsDataTypeIgnoringUserStartNodes(dataTypeKey);
entities = aids == null || aids.Contains(Constants.System.Root) || ignoreUserStartNodes entities = aids == null || aids.Contains(Constants.System.Root) || ignoreUserStartNodes