Added user start node restrictions to sibling endpoints (#19839)
* Added user start node restrictions to sibling endpoints. * Further integration tests. * Tidy up. * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Revert previous update. * Applied previous update correctly. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Services;
|
||||
|
||||
public partial class UserStartNodeEntitiesServiceMediaTests
|
||||
{
|
||||
[Test]
|
||||
public async Task SiblingUserAccessEntities_WithStartNodeOfTargetParent_YieldsAll_AsAllowed()
|
||||
{
|
||||
var mediaStartNodePaths = await CreateUserAndGetStartNodePaths(_mediaByName["1"].Id);
|
||||
|
||||
var siblings = UserStartNodeEntitiesService
|
||||
.SiblingUserAccessEntities(
|
||||
UmbracoObjectTypes.Media,
|
||||
mediaStartNodePaths,
|
||||
_mediaByName["1-5"].Key,
|
||||
2,
|
||||
2,
|
||||
BySortOrder)
|
||||
.ToArray();
|
||||
|
||||
Assert.AreEqual(5, siblings.Length);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Assert.AreEqual(_mediaByName[$"1-{i + 3}"].Key, siblings[i].Entity.Key);
|
||||
Assert.IsTrue(siblings[i].HasAccess);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SiblingUserAccessEntities_WithStartNodeOfTargetParentAndTarget_YieldsOnlyTarget_AsAllowed()
|
||||
{
|
||||
// See notes on ChildUserAccessEntities_ChildAndGrandchildAsStartNode_AllowsOnlyGrandchild.
|
||||
|
||||
var contentStartNodePaths = await CreateUserAndGetStartNodePaths(_mediaByName["1"].Id, _mediaByName["1-5"].Id);
|
||||
|
||||
var siblings = UserStartNodeEntitiesService
|
||||
.SiblingUserAccessEntities(
|
||||
UmbracoObjectTypes.Media,
|
||||
contentStartNodePaths,
|
||||
_mediaByName["1-5"].Key,
|
||||
2,
|
||||
2,
|
||||
BySortOrder)
|
||||
.ToArray();
|
||||
|
||||
Assert.AreEqual(1, siblings.Length);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(_mediaByName[$"1-5"].Key, siblings[0].Entity.Key);
|
||||
Assert.IsTrue(siblings[0].HasAccess);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SiblingUserAccessEntities_WithStartNodeOfTarget_YieldsOnlyTarget_AsAllowed()
|
||||
{
|
||||
var contentStartNodePaths = await CreateUserAndGetStartNodePaths(_mediaByName["1-5"].Id);
|
||||
|
||||
var siblings = UserStartNodeEntitiesService
|
||||
.SiblingUserAccessEntities(
|
||||
UmbracoObjectTypes.Media,
|
||||
contentStartNodePaths,
|
||||
_mediaByName["1-5"].Key,
|
||||
2,
|
||||
2,
|
||||
BySortOrder)
|
||||
.ToArray();
|
||||
|
||||
Assert.AreEqual(1, siblings.Length);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(_mediaByName[$"1-5"].Key, siblings[0].Entity.Key);
|
||||
Assert.IsTrue(siblings[0].HasAccess);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SiblingUserAccessEntities_WithStartsNodesOfTargetAndSiblings_YieldsOnlyPermitted_AsAllowed()
|
||||
{
|
||||
var mediaStartNodePaths = await CreateUserAndGetStartNodePaths(_mediaByName["1-3"].Id, _mediaByName["1-5"].Id, _mediaByName["1-7"].Id);
|
||||
|
||||
var siblings = UserStartNodeEntitiesService
|
||||
.SiblingUserAccessEntities(
|
||||
UmbracoObjectTypes.Media,
|
||||
mediaStartNodePaths,
|
||||
_mediaByName["1-5"].Key,
|
||||
2,
|
||||
2,
|
||||
BySortOrder)
|
||||
.ToArray();
|
||||
|
||||
Assert.AreEqual(3, siblings.Length);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(_mediaByName[$"1-3"].Key, siblings[0].Entity.Key);
|
||||
Assert.IsTrue(siblings[0].HasAccess);
|
||||
Assert.AreEqual(_mediaByName[$"1-5"].Key, siblings[1].Entity.Key);
|
||||
Assert.IsTrue(siblings[1].HasAccess);
|
||||
Assert.AreEqual(_mediaByName[$"1-7"].Key, siblings[2].Entity.Key);
|
||||
Assert.IsTrue(siblings[2].HasAccess);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SiblingUserAccessEntities_WithStartsNodesOfTargetGrandchild_YieldsTarget_AsNotAllowed()
|
||||
{
|
||||
var mediaStartNodePaths = await CreateUserAndGetStartNodePaths(_mediaByName["1-5-1"].Id);
|
||||
|
||||
var siblings = UserStartNodeEntitiesService
|
||||
.SiblingUserAccessEntities(
|
||||
UmbracoObjectTypes.Media,
|
||||
mediaStartNodePaths,
|
||||
_mediaByName["1-5"].Key,
|
||||
2,
|
||||
2,
|
||||
BySortOrder)
|
||||
.ToArray();
|
||||
|
||||
Assert.AreEqual(1, siblings.Length);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(_mediaByName[$"1-5"].Key, siblings[0].Entity.Key);
|
||||
Assert.IsFalse(siblings[0].HasAccess);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Services;
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Services;
|
||||
|
||||
public partial class UserStartNodeEntitiesServiceTests
|
||||
{
|
||||
[Test]
|
||||
public async Task SiblingUserAccessEntities_WithStartNodeOfTargetParent_YieldsAll_AsAllowed()
|
||||
{
|
||||
var contentStartNodePaths = await CreateUserAndGetStartNodePaths(_contentByName["1"].Id);
|
||||
|
||||
var siblings = UserStartNodeEntitiesService
|
||||
.SiblingUserAccessEntities(
|
||||
UmbracoObjectTypes.Document,
|
||||
contentStartNodePaths,
|
||||
_contentByName["1-5"].Key,
|
||||
2,
|
||||
2,
|
||||
BySortOrder)
|
||||
.ToArray();
|
||||
|
||||
Assert.AreEqual(5, siblings.Length);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Assert.AreEqual(_contentByName[$"1-{i + 3}"].Key, siblings[i].Entity.Key);
|
||||
Assert.IsTrue(siblings[i].HasAccess);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SiblingUserAccessEntities_WithStartNodeOfTargetParentAndTarget_YieldsOnlyTarget_AsAllowed()
|
||||
{
|
||||
// See notes on ChildUserAccessEntities_ChildAndGrandchildAsStartNode_AllowsOnlyGrandchild.
|
||||
|
||||
var contentStartNodePaths = await CreateUserAndGetStartNodePaths(_contentByName["1"].Id, _contentByName["1-5"].Id);
|
||||
|
||||
var siblings = UserStartNodeEntitiesService
|
||||
.SiblingUserAccessEntities(
|
||||
UmbracoObjectTypes.Document,
|
||||
contentStartNodePaths,
|
||||
_contentByName["1-5"].Key,
|
||||
2,
|
||||
2,
|
||||
BySortOrder)
|
||||
.ToArray();
|
||||
|
||||
Assert.AreEqual(1, siblings.Length);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(_contentByName[$"1-5"].Key, siblings[0].Entity.Key);
|
||||
Assert.IsTrue(siblings[0].HasAccess);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SiblingUserAccessEntities_WithStartNodeOfTarget_YieldsOnlyTarget_AsAllowed()
|
||||
{
|
||||
var contentStartNodePaths = await CreateUserAndGetStartNodePaths(_contentByName["1-5"].Id);
|
||||
|
||||
var siblings = UserStartNodeEntitiesService
|
||||
.SiblingUserAccessEntities(
|
||||
UmbracoObjectTypes.Document,
|
||||
contentStartNodePaths,
|
||||
_contentByName["1-5"].Key,
|
||||
2,
|
||||
2,
|
||||
BySortOrder)
|
||||
.ToArray();
|
||||
|
||||
Assert.AreEqual(1, siblings.Length);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(_contentByName[$"1-5"].Key, siblings[0].Entity.Key);
|
||||
Assert.IsTrue(siblings[0].HasAccess);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SiblingUserAccessEntities_WithStartsNodesOfTargetAndSiblings_YieldsOnlyPermitted_AsAllowed()
|
||||
{
|
||||
var contentStartNodePaths = await CreateUserAndGetStartNodePaths(_contentByName["1-3"].Id, _contentByName["1-5"].Id, _contentByName["1-7"].Id);
|
||||
|
||||
var siblings = UserStartNodeEntitiesService
|
||||
.SiblingUserAccessEntities(
|
||||
UmbracoObjectTypes.Document,
|
||||
contentStartNodePaths,
|
||||
_contentByName["1-5"].Key,
|
||||
2,
|
||||
2,
|
||||
BySortOrder)
|
||||
.ToArray();
|
||||
|
||||
Assert.AreEqual(3, siblings.Length);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(_contentByName[$"1-3"].Key, siblings[0].Entity.Key);
|
||||
Assert.IsTrue(siblings[0].HasAccess);
|
||||
Assert.AreEqual(_contentByName[$"1-5"].Key, siblings[1].Entity.Key);
|
||||
Assert.IsTrue(siblings[1].HasAccess);
|
||||
Assert.AreEqual(_contentByName[$"1-7"].Key, siblings[2].Entity.Key);
|
||||
Assert.IsTrue(siblings[2].HasAccess);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SiblingUserAccessEntities_WithStartNodesOfTargetChild_YieldsTarget_AsNotAllowed()
|
||||
{
|
||||
var contentStartNodePaths = await CreateUserAndGetStartNodePaths(_contentByName["1-5-1"].Id);
|
||||
|
||||
var siblings = UserStartNodeEntitiesService
|
||||
.SiblingUserAccessEntities(
|
||||
UmbracoObjectTypes.Document,
|
||||
contentStartNodePaths,
|
||||
_contentByName["1-5"].Key,
|
||||
2,
|
||||
2,
|
||||
BySortOrder)
|
||||
.ToArray();
|
||||
|
||||
Assert.AreEqual(1, siblings.Length);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(_contentByName[$"1-5"].Key, siblings[0].Entity.Key);
|
||||
Assert.IsFalse(siblings[0].HasAccess);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Services.Entities;
|
||||
using Umbraco.Cms.Core;
|
||||
@@ -32,7 +32,7 @@ public partial class UserStartNodeEntitiesServiceTests : UmbracoIntegrationTest
|
||||
|
||||
private IUserStartNodeEntitiesService UserStartNodeEntitiesService => GetRequiredService<IUserStartNodeEntitiesService>();
|
||||
|
||||
protected readonly Ordering BySortOrder = Ordering.By("sortOrder");
|
||||
protected static readonly Ordering BySortOrder = Ordering.By("sortOrder");
|
||||
|
||||
protected override void ConfigureTestServices(IServiceCollection services)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Entities;
|
||||
using Umbraco.Cms.Core.Persistence.Querying;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.ContentTypeEditing;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
@@ -936,9 +937,9 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
|
||||
{
|
||||
var children = CreateSiblingsTestData();
|
||||
|
||||
var taget = children[1];
|
||||
var target = children[1];
|
||||
|
||||
var result = EntityService.GetSiblings(taget.Key, UmbracoObjectTypes.Document, 1, 1).ToArray();
|
||||
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1).ToArray();
|
||||
Assert.AreEqual(3, result.Length);
|
||||
Assert.IsTrue(result[0].Key == children[0].Key);
|
||||
Assert.IsTrue(result[1].Key == children[1].Key);
|
||||
@@ -953,8 +954,8 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
|
||||
var trash = children[1];
|
||||
ContentService.MoveToRecycleBin(trash);
|
||||
|
||||
var taget = children[2];
|
||||
var result = EntityService.GetSiblings(taget.Key, UmbracoObjectTypes.Document, 1, 1).ToArray();
|
||||
var target = children[2];
|
||||
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1).ToArray();
|
||||
Assert.AreEqual(3, result.Length);
|
||||
Assert.IsFalse(result.Any(x => x.Key == trash.Key));
|
||||
Assert.IsTrue(result[0].Key == children[0].Key);
|
||||
@@ -962,6 +963,44 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
|
||||
Assert.IsTrue(result[2].Key == children[3].Key);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EntityService_Siblings_SkipsFilteredEntities_UsingFilterWithSet()
|
||||
{
|
||||
var children = CreateSiblingsTestData();
|
||||
|
||||
// Apply a filter that excludes the child at index 1. We'd expect to not get this, but
|
||||
// get still get one previous sibling, i.e. the entity at index 0.
|
||||
Guid[] keysToExclude = [children[1].Key];
|
||||
IQuery<IUmbracoEntity> filter = ScopeProvider.CreateQuery<IUmbracoEntity>().Where(x => !keysToExclude.Contains(x.Key));
|
||||
|
||||
var target = children[2];
|
||||
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, filter).ToArray();
|
||||
Assert.AreEqual(3, result.Length);
|
||||
Assert.IsFalse(result.Any(x => x.Key == keysToExclude[0]));
|
||||
Assert.IsTrue(result[0].Key == children[0].Key);
|
||||
Assert.IsTrue(result[1].Key == children[2].Key);
|
||||
Assert.IsTrue(result[2].Key == children[3].Key);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EntityService_Siblings_SkipsFilteredEntities_UsingFilterWithoutSet()
|
||||
{
|
||||
var children = CreateSiblingsTestData();
|
||||
|
||||
// Apply a filter that excludes the child at index 1. We'd expect to not get this, but
|
||||
// get still get one previous sibling, i.e. the entity at index 0.
|
||||
var keyToExclude = children[1].Key;
|
||||
IQuery<IUmbracoEntity> filter = ScopeProvider.CreateQuery<IUmbracoEntity>().Where(x => x.Key != keyToExclude);
|
||||
|
||||
var target = children[2];
|
||||
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, filter).ToArray();
|
||||
Assert.AreEqual(3, result.Length);
|
||||
Assert.IsFalse(result.Any(x => x.Key == keyToExclude));
|
||||
Assert.IsTrue(result[0].Key == children[0].Key);
|
||||
Assert.IsTrue(result[1].Key == children[2].Key);
|
||||
Assert.IsTrue(result[2].Key == children[3].Key);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EntityService_Siblings_RespectsOrdering()
|
||||
{
|
||||
@@ -970,8 +1009,8 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
|
||||
// Order the children by name to ensure the ordering works when differing from the default sort order, the name is a GUID.
|
||||
children = children.OrderBy(x => x.Name).ToList();
|
||||
|
||||
var taget = children[1];
|
||||
var result = EntityService.GetSiblings(taget.Key, UmbracoObjectTypes.Document, 1, 1, Ordering.By(nameof(NodeDto.Text))).ToArray();
|
||||
var target = children[1];
|
||||
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, ordering: Ordering.By(nameof(NodeDto.Text))).ToArray();
|
||||
Assert.AreEqual(3, result.Length);
|
||||
Assert.IsTrue(result[0].Key == children[0].Key);
|
||||
Assert.IsTrue(result[1].Key == children[1].Key);
|
||||
@@ -983,8 +1022,8 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
|
||||
{
|
||||
var children = CreateSiblingsTestData();
|
||||
|
||||
var taget = children[1];
|
||||
var result = EntityService.GetSiblings(taget.Key, UmbracoObjectTypes.Document, 100, 1).ToArray();
|
||||
var target = children[1];
|
||||
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 100, 1).ToArray();
|
||||
Assert.AreEqual(3, result.Length);
|
||||
Assert.IsTrue(result[0].Key == children[0].Key);
|
||||
Assert.IsTrue(result[1].Key == children[1].Key);
|
||||
@@ -996,8 +1035,8 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
|
||||
{
|
||||
var children = CreateSiblingsTestData();
|
||||
|
||||
var taget = children[^2];
|
||||
var result = EntityService.GetSiblings(taget.Key, UmbracoObjectTypes.Document, 1, 100).ToArray();
|
||||
var target = children[^2];
|
||||
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 100).ToArray();
|
||||
Assert.AreEqual(3, result.Length);
|
||||
Assert.IsTrue(result[^1].Key == children[^1].Key);
|
||||
Assert.IsTrue(result[^2].Key == children[^2].Key);
|
||||
|
||||
@@ -286,12 +286,18 @@
|
||||
<Compile Update="ManagementApi\Services\UserStartNodeEntitiesServiceTests.RootUserAccessEntities.cs">
|
||||
<DependentUpon>UserStartNodeEntitiesServiceTests.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="ManagementApi\Services\UserStartNodeEntitiesServiceTests.SiblingUserAccessEntities.cs">
|
||||
<DependentUpon>UserStartNodeEntitiesServiceTests.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="ManagementApi\Services\UserStartNodeEntitiesServiceMediaTests.childUserAccessEntities.cs">
|
||||
<DependentUpon>UserStartNodeEntitiesServiceMediaTests.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="ManagementApi\Services\UserStartNodeEntitiesServiceMediaTests.RootUserAccessEntities.cs">
|
||||
<DependentUpon>UserStartNodeEntitiesServiceMediaTests.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="ManagementApi\Services\UserStartNodeEntitiesServiceMediaTests.SiblingUserAccessEntities.cs">
|
||||
<DependentUpon>UserStartNodeEntitiesServiceMediaTests.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Umbraco.Infrastructure\Services\ContentBlueprintEditingServiceTests.GetScaffold.cs">
|
||||
<DependentUpon>ContentBlueprintEditingServiceTests.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
||||
Reference in New Issue
Block a user