diff --git a/src/Umbraco.Core/Models/Mapping/ContentVariantMapper.cs b/src/Umbraco.Core/Models/Mapping/ContentVariantMapper.cs index 4bab057cbe..d909ef9c91 100644 --- a/src/Umbraco.Core/Models/Mapping/ContentVariantMapper.cs +++ b/src/Umbraco.Core/Models/Mapping/ContentVariantMapper.cs @@ -216,9 +216,16 @@ public class ContentVariantMapper private IEnumerable GetLanguagePermissions(IContent content, MapperContext context, TVariant variantDisplay) where TVariant : ContentVariantDisplay { + context.Items.TryGetValue("CurrentUser", out var currentBackofficeUser); + + IEnumerable? userGroups = null; + if (currentBackofficeUser is IUser currentIUserBackofficeUser) + { + userGroups = currentIUserBackofficeUser.Groups; + } + // Map allowed actions - IEnumerable? userGroups = - _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Groups; + userGroups ??= _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Groups; bool hasAccess = false; if (userGroups is not null) { diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Extensions/ContentVariantAllowedActionTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Extensions/ContentVariantAllowedActionTests.cs new file mode 100644 index 0000000000..1c4142e287 --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Extensions/ContentVariantAllowedActionTests.cs @@ -0,0 +1,87 @@ +using System.Linq; +using NUnit.Framework; +using Umbraco.Cms.Core.Actions; +using Umbraco.Cms.Core.Mapping; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.ContentEditing; +using Umbraco.Cms.Core.Models.Membership; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Tests.Common.Builders; +using Umbraco.Cms.Tests.Common.Builders.Extensions; +using Umbraco.Cms.Tests.Integration.TestServerTest; +using Language = Umbraco.Cms.Core.Models.Language; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Extensions; + +[TestFixture] +public class ContentVariantAllowedActionTests : UmbracoTestServerTestBase +{ + private const string UsIso = "en-US"; + private const string DkIso = "da-DK"; + private ILocalizationService LocalizationService => GetRequiredService(); + + private IUserService UserService => GetRequiredService(); + + private IUmbracoMapper UmbracoMapper => GetRequiredService(); + + [SetUp] + public void SetUpTestDate() + { + var dk = new Language(DkIso, "Danish"); + LocalizationService.Save(dk); + } + + [Test] + public void CanCheckIfUserHasAccessToLanguage() + { + // setup user groups + var user = UserBuilder.CreateUser(); + UserService.Save(user); + + var userGroup = UserGroupBuilder.CreateUserGroup(); + var languageId = LocalizationService.GetLanguageIdByIsoCode(DkIso); + userGroup.AddAllowedLanguage(languageId!.Value); + UserService.Save(userGroup, new []{ user.Id}); + var currentUser = UserService.GetUserById(user.Id); + + var result = CreateContent(currentUser); + + var danishVariant = result.Variants.FirstOrDefault(x => x.Language!.IsoCode is DkIso); + var usVariant = result.Variants.FirstOrDefault(x => x.Language!.IsoCode is UsIso); + + // Right now we duplicate allowedActions if you have access, this should be changed + // when we implement granular permissions for languages + Assert.AreEqual(danishVariant!.AllowedActions, result.AllowedActions); + Assert.AreEqual(usVariant!.AllowedActions, new [] { ActionBrowse.ActionLetter.ToString() }); + } + + private ContentItemDisplay CreateContent(IUser user) + { + var contentTypeService = GetRequiredService(); + var contentType = new ContentTypeBuilder().WithContentVariation(ContentVariation.Culture).Build(); + contentTypeService.Save(contentType); + + var rootNode = new ContentBuilder() + .WithoutIdentity() + .WithContentType(contentType) + .WithCultureName(UsIso, "Root") + .WithCultureName(DkIso, "Rod") + .Build(); + + var contentService = GetRequiredService(); + contentService.SaveAndPublish(rootNode); + + ContentItemDisplay? display = UmbracoMapper.Map(rootNode, context => + { + context.Items["CurrentUser"] = user; + }); + + if (display is not null) + { + display.AllowPreview = display.AllowPreview && rootNode?.Trashed == false && + rootNode.ContentType.IsElement == false; + } + + return display; + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Extensions/ReadOnlyUserGroupExtensionsTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Extensions/ReadOnlyUserGroupExtensionsTests.cs deleted file mode 100644 index f2463ce409..0000000000 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Extensions/ReadOnlyUserGroupExtensionsTests.cs +++ /dev/null @@ -1,30 +0,0 @@ -using NUnit.Framework; -using Umbraco.Cms.Core.Extensions; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Models.Membership; -using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Core.Strings; -using Umbraco.Cms.Tests.Common.Testing; -using Umbraco.Cms.Tests.Integration.Testing; - -namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Extensions; - -[TestFixture] -[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)] -public class ReadOnlyUserGroupExtensionsTests : UmbracoIntegrationTest -{ - private ILocalizationService LocalizationService => GetRequiredService(); - - private IShortStringHelper ShortStringHelper => GetRequiredService(); - - [Test] - public void CanIfUserHasAccessToLanguage() - { - var swe = new Language("sv-SE", "Swedish"); - LocalizationService.Save(swe); - var userGrp = new UserGroup(ShortStringHelper); - userGrp.AddAllowedLanguage(swe.Id); - - Assert.IsTrue(userGrp.HasAccessToLanguage(swe.Id)); - } -} diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Extensions/ReadOnlyUserGroupExtensions.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Extensions/ReadOnlyUserGroupExtensions.cs new file mode 100644 index 0000000000..ea50d77438 --- /dev/null +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Extensions/ReadOnlyUserGroupExtensions.cs @@ -0,0 +1,42 @@ +using NUnit.Framework; +using Umbraco.Cms.Core.Extensions; +using Umbraco.Cms.Core.Models.Membership; +using Umbraco.Cms.Tests.UnitTests.Umbraco.Core.ShortStringHelper; + +namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Extensions; + +[TestFixture] +public class ReadOnlyUserGroupExtensions +{ + private static int _swedishLanguageId = 1; + private static int _danishLanguageId = 2; + private static int _germanLanguageId = 3 ; + + [Test] + public void CanCheckIfUserHasAccessToLanguage() + { + var userGrp = new UserGroup(new MockShortStringHelper()); + userGrp.AddAllowedLanguage(_swedishLanguageId); + userGrp.AddAllowedLanguage(_danishLanguageId); + + Assert.Multiple(() => + { + Assert.IsTrue(userGrp.HasAccessToLanguage(_swedishLanguageId)); + Assert.IsTrue(userGrp.HasAccessToLanguage(_danishLanguageId)); + Assert.IsFalse(userGrp.HasAccessToLanguage(_germanLanguageId)); + }); + } + + [Test] + public void CheckIfAllowedLanugagesIsEmptyMeansAccessToAllLanguages() + { + var userGrp = new UserGroup(new MockShortStringHelper()); + + Assert.Multiple(() => + { + Assert.IsTrue(userGrp.HasAccessToLanguage(_swedishLanguageId)); + Assert.IsTrue(userGrp.HasAccessToLanguage(_danishLanguageId)); + Assert.IsTrue(userGrp.HasAccessToLanguage(_germanLanguageId)); + }); + } +}