From 545d64df2594f4d308981e61ef7cf04d1a395f7b Mon Sep 17 00:00:00 2001 From: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> Date: Tue, 17 Dec 2024 13:26:27 +0100 Subject: [PATCH] V15: Handle empty permissions (#17801) * Handle empty permissions * Add tests * Add a few more asserts to the tests * Move dependency injection to test itself --------- Co-authored-by: Kenn Jacobsen --- .../Permissions/DocumentPermissionMapper.cs | 29 ++- .../UserGroupPresentationFactoryTests.cs | 168 ++++++++++++++++++ 2 files changed, 190 insertions(+), 7 deletions(-) create mode 100644 tests/Umbraco.Tests.Integration/ManagementApi/Factories/UserGroupPresentationFactoryTests.cs diff --git a/src/Umbraco.Cms.Api.Management/Mapping/Permissions/DocumentPermissionMapper.cs b/src/Umbraco.Cms.Api.Management/Mapping/Permissions/DocumentPermissionMapper.cs index afdbd0f618..55c66221fc 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/Permissions/DocumentPermissionMapper.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/Permissions/DocumentPermissionMapper.cs @@ -42,16 +42,31 @@ public class DocumentPermissionMapper : IPermissionPresentationMapper, IPermissi public IEnumerable MapToGranularPermissions(IPermissionPresentationModel permissionViewModel) { - if (permissionViewModel is DocumentPermissionPresentationModel documentPermissionPresentationModel) + if (permissionViewModel is not DocumentPermissionPresentationModel documentPermissionPresentationModel) { - foreach (var verb in documentPermissionPresentationModel.Verbs) + yield break; + } + + if(documentPermissionPresentationModel.Verbs.Any() is false || (documentPermissionPresentationModel.Verbs.Count == 1 && documentPermissionPresentationModel.Verbs.Contains(string.Empty))) + { + yield return new DocumentGranularPermission { - yield return new DocumentGranularPermission - { - Key = documentPermissionPresentationModel.Document.Id, - Permission = verb, - }; + Key = documentPermissionPresentationModel.Document.Id, + Permission = string.Empty, + }; + yield break; + } + foreach (var verb in documentPermissionPresentationModel.Verbs) + { + if (string.IsNullOrEmpty(verb)) + { + continue; } + yield return new DocumentGranularPermission + { + Key = documentPermissionPresentationModel.Document.Id, + Permission = verb, + }; } } } diff --git a/tests/Umbraco.Tests.Integration/ManagementApi/Factories/UserGroupPresentationFactoryTests.cs b/tests/Umbraco.Tests.Integration/ManagementApi/Factories/UserGroupPresentationFactoryTests.cs new file mode 100644 index 0000000000..8a27922276 --- /dev/null +++ b/tests/Umbraco.Tests.Integration/ManagementApi/Factories/UserGroupPresentationFactoryTests.cs @@ -0,0 +1,168 @@ +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; +using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Mapping.Permissions; +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Api.Management.ViewModels.UserGroup; +using Umbraco.Cms.Api.Management.ViewModels.UserGroup.Permissions; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Services.ContentTypeEditing; +using Umbraco.Cms.Core.Services.OperationStatus; +using Umbraco.Cms.Infrastructure.Persistence.Mappers; +using Umbraco.Cms.Tests.Common.Builders; +using Umbraco.Cms.Tests.Common.TestHelpers; +using Umbraco.Cms.Tests.Common.Testing; +using Umbraco.Cms.Tests.Integration.Testing; + +namespace Umbraco.Cms.Tests.Integration.ManagementApi.Factories; + +[TestFixture] +[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] +public class UserGroupPresentationFactoryTests : UmbracoIntegrationTest +{ + public IUserGroupPresentationFactory UserGroupPresentationFactory => GetRequiredService(); + public IUserGroupService UserGroupService => GetRequiredService(); + public ITemplateService TemplateService => GetRequiredService(); + public IContentTypeEditingService ContentTypeEditingService => GetRequiredService(); + + public IContentEditingService ContentEditingService => GetRequiredService(); + + protected override void ConfigureTestServices(IServiceCollection services) + { + services.AddTransient(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(x=>x.GetRequiredService()); + services.AddSingleton(x=>x.GetRequiredService()); + } + + + [Test] + public async Task Can_Map_Create_Model_And_Create() + { + var updateModel = new CreateUserGroupRequestModel() + { + Alias = "testAlias", + FallbackPermissions = new HashSet(), + HasAccessToAllLanguages = true, + Languages = new List(), + Name = "Test Name", + Sections = new [] {"Umb.Section.Content"}, + Permissions = new HashSet() + }; + + var attempt = await UserGroupPresentationFactory.CreateAsync(updateModel); + Assert.IsTrue(attempt.Success); + + var userGroupCreateAttempt = await UserGroupService.CreateAsync(attempt.Result, Constants.Security.SuperUserKey); + + var userGroup = userGroupCreateAttempt.Result; + + Assert.Multiple(() => + { + Assert.IsTrue(userGroupCreateAttempt.Success); + Assert.IsNotNull(userGroup); + Assert.IsEmpty(userGroup.GranularPermissions); + }); + } + + [Test] + public async Task Cannot_Create_UserGroup_With_Unexisting_Document_Reference() + { + var updateModel = new CreateUserGroupRequestModel() + { + Alias = "testAlias", + FallbackPermissions = new HashSet(), + HasAccessToAllLanguages = true, + Languages = new List(), + Name = "Test Name", + Sections = new [] {"Umb.Section.Content"}, + Permissions = new HashSet() + { + new DocumentPermissionPresentationModel() + { + Document = new ReferenceByIdModel(Guid.NewGuid()), + Verbs = new HashSet() + } + } + }; + + var attempt = await UserGroupPresentationFactory.CreateAsync(updateModel); + Assert.IsTrue(attempt.Success); + + var userGroupCreateAttempt = await UserGroupService.CreateAsync(attempt.Result, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsFalse(userGroupCreateAttempt.Success); + Assert.AreEqual(UserGroupOperationStatus.DocumentPermissionKeyNotFound, userGroupCreateAttempt.Status); + }); + } + + [Test] + public async Task Can_Create_Usergroup_With_Empty_Granluar_Permissions_For_Document() + { + var contentKey = await CreateContent(); + + var updateModel = new CreateUserGroupRequestModel() + { + Alias = "testAlias", + FallbackPermissions = new HashSet(), + HasAccessToAllLanguages = true, + Languages = new List(), + Name = "Test Name", + Sections = new [] {"Umb.Section.Content"}, + Permissions = new HashSet + { + new DocumentPermissionPresentationModel() + { + Document = new ReferenceByIdModel(contentKey), + Verbs = new HashSet() + } + } + }; + + var attempt = await UserGroupPresentationFactory.CreateAsync(updateModel); + Assert.IsTrue(attempt.Success); + + var userGroupCreateAttempt = await UserGroupService.CreateAsync(attempt.Result, Constants.Security.SuperUserKey); + var userGroup = userGroupCreateAttempt.Result; + + Assert.Multiple(() => + { + Assert.IsTrue(userGroupCreateAttempt.Success); + Assert.IsNotNull(userGroup); + Assert.IsNotEmpty(userGroup.GranularPermissions); + Assert.AreEqual(contentKey, userGroup.GranularPermissions.First().Key); + Assert.AreEqual(string.Empty, userGroup.GranularPermissions.First().Permission); + }); + } + + private async Task CreateContent() + { + // NOTE Maybe not the best way to create/save test data as we are using the services, which are being tested. + var template = TemplateBuilder.CreateTextPageTemplate("defaultTemplate"); + await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey); + // Create and Save ContentType "umbTextpage" -> 1051 (template), 1052 (content type) + var contentTypeCreateModel = ContentTypeEditingBuilder.CreateSimpleContentType("umbTextpage", "Textpage", defaultTemplateKey: template.Key); + var contentTypeAttempt = await ContentTypeEditingService.CreateAsync(contentTypeCreateModel, Constants.Security.SuperUserKey); + Assert.IsTrue(contentTypeAttempt.Success); + + var contentTypeResult = contentTypeAttempt.Result; + var contentTypeUpdateModel = ContentTypeUpdateHelper.CreateContentTypeUpdateModel(contentTypeResult); contentTypeUpdateModel.AllowedContentTypes = new[] + { + new ContentTypeSort(contentTypeResult.Key, 0, contentTypeCreateModel.Alias), + }; + var updatedContentTypeResult = await ContentTypeEditingService.UpdateAsync(contentTypeResult, contentTypeUpdateModel, Constants.Security.SuperUserKey); + Assert.IsTrue(updatedContentTypeResult.Success); + + // Create and Save Content "Homepage" based on "umbTextpage" -> 1053 + var textPage = ContentEditingBuilder.CreateSimpleContent(updatedContentTypeResult.Result.Key); + var createContentResultTextPage = await ContentEditingService.CreateAsync(textPage, Constants.Security.SuperUserKey); + Assert.IsTrue(createContentResultTextPage.Success); + + return createContentResultTextPage.Result.Content.Key; + } +}