Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@ IEnumerable<IEntitySlim> GetTrashedSiblings(
/// <returns>A collection of entity paths.</returns>
IEnumerable<TreeEntityPath> GetAllPaths(Guid objectType, params Guid[] keys);

/// <summary>
/// Gets all paths for entities of the specified object types, optionally filtered by the provided entity IDs.
/// </summary>
/// <param name="objectTypes">The unique identifiers of the object types.</param>
/// <param name="keys">Optional array of entity keys to filter the paths. If not provided, paths for all entities of the specified type are returned.</param>
/// <returns>A collection of entity paths.</returns>
IEnumerable<TreeEntityPath> GetAllPaths(Guid[] objectTypes, params Guid[] keys);

/// <summary>
/// Checks whether an entity with the specified identifier exists.
/// </summary>
Expand Down
26 changes: 14 additions & 12 deletions src/Umbraco.Core/Services/ElementPermissionService.cs
Comment thread
kjac marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services.AuthorizationStatus;
using Umbraco.Extensions;

Expand Down Expand Up @@ -39,25 +40,26 @@ public Task<ElementAuthorizationStatus> AuthorizeAccessAsync(
return Task.FromResult(ElementAuthorizationStatus.NotFound);
}

// Fetch both Elements and ElementContainers (folders)
IEntitySlim[] entities = _entityService.GetAll(
new[] { UmbracoObjectTypes.Element, UmbracoObjectTypes.ElementContainer },
keys).ToArray();

if (entities.Length == 0)
// Use GetAllPaths instead of loading full content items - we only need paths for authorization
TreeEntityPath[] entityPaths = _entityService.GetAllPaths([UmbracoObjectTypes.Element, UmbracoObjectTypes.ElementContainer], keys).ToArray();
if (entityPaths.Length == 0)
{
return Task.FromResult(ElementAuthorizationStatus.NotFound);
}

if (entities.Any(entity => user.HasElementPathAccess(entity, _entityService, _appCaches) == false))
// Check path access using the paths directly
int[]? startNodeIds = user.CalculateElementStartNodeIds(_entityService, _appCaches);
foreach (TreeEntityPath entityPath in entityPaths)
{
return Task.FromResult(ElementAuthorizationStatus.UnauthorizedMissingPathAccess);
if (ContentPermissions.HasPathAccess(entityPath.Path, startNodeIds, Constants.System.RecycleBinElement) == false)
{
return Task.FromResult(ElementAuthorizationStatus.UnauthorizedMissingPathAccess);
}
}

return Task.FromResult(
HasPermissionAccess(user, entities.Select(e => e.Path), permissionsToCheck)
? ElementAuthorizationStatus.Success
: ElementAuthorizationStatus.UnauthorizedMissingPermissionAccess);
return Task.FromResult(HasPermissionAccess(user, entityPaths.Select(p => p.Path), permissionsToCheck)
? ElementAuthorizationStatus.Success
: ElementAuthorizationStatus.UnauthorizedMissingPermissionAccess);
}

/// <inheritdoc/>
Expand Down
9 changes: 9 additions & 0 deletions src/Umbraco.Core/Services/EntityService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Globalization;

Check notice on line 1 in src/Umbraco.Core/Services/EntityService.cs

View check run for this annotation

CodeScene Delta Analysis / CodeScene Code Health Review (v18/dev)

✅ Getting better: Primitive Obsession

The ratio of primitive types in function arguments decreases from 56.35% to 56.28%, threshold = 30.0%. The functions in this file have too many primitive types (e.g. int, double, float) in their function argument lists. Using many primitive types lead to the code smell Primitive Obsession. Avoid adding more primitive arguments.
using System.Linq.Expressions;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Events;
Expand Down Expand Up @@ -831,6 +831,15 @@
}
}

/// <inheritdoc />
public virtual IEnumerable<TreeEntityPath> GetAllPaths(IEnumerable<UmbracoObjectTypes> objectTypes, params Guid[] keys)
{
using (ScopeProvider.CreateCoreScope(autoComplete: true))
{
return _entityRepository.GetAllPaths(objectTypes.Select(objectType => objectType.GetGuid()).ToArray(), keys);
}
}

/// <inheritdoc />
public int ReserveId(Guid key)
{
Expand Down
5 changes: 5 additions & 0 deletions src/Umbraco.Core/Services/IEntityService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,11 @@ IEnumerable<IEntitySlim> GetPagedDescendants(
/// </summary>
IEnumerable<TreeEntityPath> GetAllPaths(UmbracoObjectTypes objectType, params Guid[] keys);

/// <summary>
/// Gets paths for entities.
/// </summary>
IEnumerable<TreeEntityPath> GetAllPaths(IEnumerable<UmbracoObjectTypes> objectTypes, params Guid[] keys);

/// <summary>
/// Reserves an identifier for a key.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -587,14 +587,23 @@ public IEnumerable<TreeEntityPath> GetAllPaths(Guid objectType, params Guid[] ke
? PerformGetAllPaths(objectType, sql => sql.WhereIn<NodeDto>(x => x.UniqueId, keys.Distinct()))
: PerformGetAllPaths(objectType);

/// <inheritdoc/>
public IEnumerable<TreeEntityPath> GetAllPaths(Guid[] objectTypes, params Guid[] keys) =>
keys.Any()
? PerformGetAllPaths(objectTypes, sql => sql.WhereIn<NodeDto>(x => x.UniqueId, keys.Distinct()))
: PerformGetAllPaths(objectTypes);

private IEnumerable<TreeEntityPath> PerformGetAllPaths(Guid objectType, Action<Sql<ISqlContext>>? filter = null)
=> PerformGetAllPaths([objectType], filter);

private IEnumerable<TreeEntityPath> PerformGetAllPaths(Guid[] objectTypes, Action<Sql<ISqlContext>>? filter = null)
{
// NodeId is named Id on TreeEntityPath = use an alias
Sql<ISqlContext> sql = Sql().Select<NodeDto>(
x => Alias(x.NodeId, nameof(TreeEntityPath.Id)),
x => x.Path,
x => Alias(x.UniqueId, nameof(TreeEntityPath.Key)))
.From<NodeDto>().Where<NodeDto>(x => x.NodeObjectType == objectType);
.From<NodeDto>().WhereIn<NodeDto>(x => x.NodeObjectType, objectTypes);
filter?.Invoke(sql);
return Database.Fetch<TreeEntityPath>(sql);
}
Expand Down
Loading
Loading