diff --git a/src/Umbraco.Core/Cache/CacheKeys.cs b/src/Umbraco.Core/Cache/CacheKeys.cs
index b8ee0e97c4..0e9a9a3862 100644
--- a/src/Umbraco.Core/Cache/CacheKeys.cs
+++ b/src/Umbraco.Core/Cache/CacheKeys.cs
@@ -12,5 +12,10 @@
public const string MacroContentCacheKey = "macroContent_"; // used in MacroRenderers
public const string MacroFromAliasCacheKey = "macroFromAlias_";
+
+ public const string UserAllContentStartNodesPrefix = "AllContentStartNodes";
+ public const string UserAllMediaStartNodesPrefix = "AllMediaStartNodes";
+ public const string UserMediaStartNodePathsPrefix = "MediaStartNodePaths";
+ public const string UserContentStartNodePathsPrefix = "ContentStartNodePaths";
}
}
diff --git a/src/Umbraco.Core/Models/Identity/IdentityMapDefinition.cs b/src/Umbraco.Core/Models/Identity/IdentityMapDefinition.cs
index 57e1c9ee5c..2d7eda0bc2 100644
--- a/src/Umbraco.Core/Models/Identity/IdentityMapDefinition.cs
+++ b/src/Umbraco.Core/Models/Identity/IdentityMapDefinition.cs
@@ -1,4 +1,6 @@
using System;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models.Membership;
@@ -11,12 +13,27 @@ namespace Umbraco.Core.Models.Identity
private readonly ILocalizedTextService _textService;
private readonly IEntityService _entityService;
private readonly IGlobalSettings _globalSettings;
+ private readonly AppCaches _appCaches;
- public IdentityMapDefinition(ILocalizedTextService textService, IEntityService entityService, IGlobalSettings globalSettings)
+ [Obsolete("Use constructor specifying all dependencies")]
+ public IdentityMapDefinition(
+ ILocalizedTextService textService,
+ IEntityService entityService,
+ IGlobalSettings globalSettings)
+ : this(textService, entityService, globalSettings, Current.AppCaches)
+ {
+ }
+
+ public IdentityMapDefinition(
+ ILocalizedTextService textService,
+ IEntityService entityService,
+ IGlobalSettings globalSettings,
+ AppCaches appCaches)
{
_textService = textService;
_entityService = entityService;
_globalSettings = globalSettings;
+ _appCaches = appCaches;
}
public void DefineMaps(UmbracoMapper mapper)
@@ -46,8 +63,8 @@ namespace Umbraco.Core.Models.Identity
target.Groups = source.Groups.ToArray();
*/
- target.CalculatedMediaStartNodeIds = source.CalculateMediaStartNodeIds(_entityService);
- target.CalculatedContentStartNodeIds = source.CalculateContentStartNodeIds(_entityService);
+ target.CalculatedMediaStartNodeIds = source.CalculateMediaStartNodeIds(_entityService, _appCaches);
+ target.CalculatedContentStartNodeIds = source.CalculateContentStartNodeIds(_entityService, _appCaches);
target.Email = source.Email;
target.UserName = source.Username;
target.LastPasswordChangeDateUtc = source.LastPasswordChangeDate.ToUniversalTime();
diff --git a/src/Umbraco.Core/Models/Membership/User.cs b/src/Umbraco.Core/Models/Membership/User.cs
index 3d071b0a18..dc39463925 100644
--- a/src/Umbraco.Core/Models/Membership/User.cs
+++ b/src/Umbraco.Core/Models/Membership/User.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
using Umbraco.Core.Composing;
@@ -384,11 +385,10 @@ namespace Umbraco.Core.Models.Membership
#endregion
- ///
- /// This is used as an internal cache for this entity - specifically for calculating start nodes so we don't re-calculated all of the time
- ///
[IgnoreDataMember]
[DoNotClone]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [Obsolete("This should not be used, it's currently used for only a single edge case - should probably be removed for netcore")]
internal IDictionary AdditionalData
{
get
@@ -402,6 +402,8 @@ namespace Umbraco.Core.Models.Membership
[IgnoreDataMember]
[DoNotClone]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [Obsolete("Not used, will be removed in future versions")]
internal object AdditionalDataLock => _additionalDataLock;
protected override void PerformDeepClone(object clone)
diff --git a/src/Umbraco.Core/Models/UserExtensions.cs b/src/Umbraco.Core/Models/UserExtensions.cs
index 5be66bac47..fdb833a821 100644
--- a/src/Umbraco.Core/Models/UserExtensions.cs
+++ b/src/Umbraco.Core/Models/UserExtensions.cs
@@ -150,48 +150,40 @@ namespace Umbraco.Core.Models
}
}
- internal static bool HasContentRootAccess(this IUser user, IEntityService entityService)
- {
- return ContentPermissionsHelper.HasPathAccess(Constants.System.RootString, user.CalculateContentStartNodeIds(entityService), Constants.System.RecycleBinContent);
- }
+ internal static bool HasContentRootAccess(this IUser user, IEntityService entityService, AppCaches appCaches)
+ => ContentPermissionsHelper.HasPathAccess(Constants.System.RootString, user.CalculateContentStartNodeIds(entityService, appCaches), Constants.System.RecycleBinContent);
- internal static bool HasContentBinAccess(this IUser user, IEntityService entityService)
- {
- return ContentPermissionsHelper.HasPathAccess(Constants.System.RecycleBinContentString, user.CalculateContentStartNodeIds(entityService), Constants.System.RecycleBinContent);
- }
+ internal static bool HasContentBinAccess(this IUser user, IEntityService entityService, AppCaches appCaches)
+ => ContentPermissionsHelper.HasPathAccess(Constants.System.RecycleBinContentString, user.CalculateContentStartNodeIds(entityService, appCaches), Constants.System.RecycleBinContent);
- internal static bool HasMediaRootAccess(this IUser user, IEntityService entityService)
- {
- return ContentPermissionsHelper.HasPathAccess(Constants.System.RootString, user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia);
- }
+ internal static bool HasMediaRootAccess(this IUser user, IEntityService entityService, AppCaches appCaches)
+ => ContentPermissionsHelper.HasPathAccess(Constants.System.RootString, user.CalculateMediaStartNodeIds(entityService, appCaches), Constants.System.RecycleBinMedia);
- internal static bool HasMediaBinAccess(this IUser user, IEntityService entityService)
- {
- return ContentPermissionsHelper.HasPathAccess(Constants.System.RecycleBinMediaString, user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia);
- }
+ internal static bool HasMediaBinAccess(this IUser user, IEntityService entityService, AppCaches appCaches)
+ => ContentPermissionsHelper.HasPathAccess(Constants.System.RecycleBinMediaString, user.CalculateMediaStartNodeIds(entityService, appCaches), Constants.System.RecycleBinMedia);
- internal static bool HasPathAccess(this IUser user, IContent content, IEntityService entityService)
+ internal static bool HasPathAccess(this IUser user, IContent content, IEntityService entityService, AppCaches appCaches)
{
if (content == null) throw new ArgumentNullException(nameof(content));
- return ContentPermissionsHelper.HasPathAccess(content.Path, user.CalculateContentStartNodeIds(entityService), Constants.System.RecycleBinContent);
+ return ContentPermissionsHelper.HasPathAccess(content.Path, user.CalculateContentStartNodeIds(entityService, appCaches), Constants.System.RecycleBinContent);
}
- internal static bool HasPathAccess(this IUser user, IMedia media, IEntityService entityService)
+ internal static bool HasPathAccess(this IUser user, IMedia media, IEntityService entityService, AppCaches appCaches)
{
if (media == null) throw new ArgumentNullException(nameof(media));
- return ContentPermissionsHelper.HasPathAccess(media.Path, user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia);
+ return ContentPermissionsHelper.HasPathAccess(media.Path, user.CalculateMediaStartNodeIds(entityService, appCaches), Constants.System.RecycleBinMedia);
}
- internal static bool HasContentPathAccess(this IUser user, IUmbracoEntity entity, IEntityService entityService)
+ internal static bool HasContentPathAccess(this IUser user, IUmbracoEntity entity, IEntityService entityService, AppCaches appCaches)
{
if (entity == null) throw new ArgumentNullException(nameof(entity));
- return ContentPermissionsHelper.HasPathAccess(entity.Path, user.CalculateContentStartNodeIds(entityService), Constants.System.RecycleBinContent);
+ return ContentPermissionsHelper.HasPathAccess(entity.Path, user.CalculateContentStartNodeIds(entityService, appCaches), Constants.System.RecycleBinContent);
}
- internal static bool HasMediaPathAccess(this IUser user, IUmbracoEntity entity, IEntityService entityService)
+ internal static bool HasMediaPathAccess(this IUser user, IUmbracoEntity entity, IEntityService entityService, AppCaches appCaches)
{
if (entity == null) throw new ArgumentNullException(nameof(entity));
- return ContentPermissionsHelper.HasPathAccess(entity.Path, user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia);
+ return ContentPermissionsHelper.HasPathAccess(entity.Path, user.CalculateMediaStartNodeIds(entityService, appCaches), Constants.System.RecycleBinMedia);
}
///
@@ -204,84 +196,92 @@ namespace Umbraco.Core.Models
return user.Groups != null && user.Groups.Any(x => x.Alias == Constants.Security.SensitiveDataGroupAlias);
}
- // calc. start nodes, combining groups' and user's, and excluding what's in the bin
+ [Obsolete("Use the overload specifying all parameters instead")]
public static int[] CalculateContentStartNodeIds(this IUser user, IEntityService entityService)
- {
- const string cacheKey = "AllContentStartNodes";
- //try to look them up from cache so we don't recalculate
- var valuesInUserCache = FromUserCache(user, cacheKey);
- if (valuesInUserCache != null) return valuesInUserCache;
+ => CalculateContentStartNodeIds(user, entityService, Current.AppCaches);
- var gsn = user.Groups.Where(x => x.StartContentId.HasValue).Select(x => x.StartContentId.Value).Distinct().ToArray();
- var usn = user.StartContentIds;
- var vals = CombineStartNodes(UmbracoObjectTypes.Document, gsn, usn, entityService);
- ToUserCache(user, cacheKey, vals);
- return vals;
+ ///
+ /// Calculate start nodes, combining groups' and user's, and excluding what's in the bin
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int[] CalculateContentStartNodeIds(this IUser user, IEntityService entityService, AppCaches appCaches)
+ {
+ var cacheKey = CacheKeys.UserAllContentStartNodesPrefix + user.Id;
+ var runtimeCache = appCaches.IsolatedCaches.GetOrCreate();
+ var result = runtimeCache.GetCacheItem(cacheKey, () =>
+ {
+ var gsn = user.Groups.Where(x => x.StartContentId.HasValue).Select(x => x.StartContentId.Value).Distinct().ToArray();
+ var usn = user.StartContentIds;
+ var vals = CombineStartNodes(UmbracoObjectTypes.Document, gsn, usn, entityService);
+ return vals;
+ }, TimeSpan.FromMinutes(2), true);
+
+ return result;
}
- // calc. start nodes, combining groups' and user's, and excluding what's in the bin
+ [Obsolete("Use the overload specifying all parameters instead")]
public static int[] CalculateMediaStartNodeIds(this IUser user, IEntityService entityService)
- {
- const string cacheKey = "AllMediaStartNodes";
- //try to look them up from cache so we don't recalculate
- var valuesInUserCache = FromUserCache(user, cacheKey);
- if (valuesInUserCache != null) return valuesInUserCache;
+ => CalculateMediaStartNodeIds(user, entityService, Current.AppCaches);
- var gsn = user.Groups.Where(x => x.StartMediaId.HasValue).Select(x => x.StartMediaId.Value).Distinct().ToArray();
- var usn = user.StartMediaIds;
- var vals = CombineStartNodes(UmbracoObjectTypes.Media, gsn, usn, entityService);
- ToUserCache(user, cacheKey, vals);
- return vals;
+ ///
+ /// Calculate start nodes, combining groups' and user's, and excluding what's in the bin
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int[] CalculateMediaStartNodeIds(this IUser user, IEntityService entityService, AppCaches appCaches)
+ {
+ var cacheKey = CacheKeys.UserAllMediaStartNodesPrefix + user.Id;
+ var runtimeCache = appCaches.IsolatedCaches.GetOrCreate();
+ var result = runtimeCache.GetCacheItem(cacheKey, () =>
+ {
+ var gsn = user.Groups.Where(x => x.StartMediaId.HasValue).Select(x => x.StartMediaId.Value).Distinct().ToArray();
+ var usn = user.StartMediaIds;
+ var vals = CombineStartNodes(UmbracoObjectTypes.Media, gsn, usn, entityService);
+ return vals;
+ }, TimeSpan.FromMinutes(2), true);
+
+ return result;
}
+ [Obsolete("Use the overload specifying all parameters instead")]
public static string[] GetMediaStartNodePaths(this IUser user, IEntityService entityService)
- {
- const string cacheKey = "MediaStartNodePaths";
- //try to look them up from cache so we don't recalculate
- var valuesInUserCache = FromUserCache(user, cacheKey);
- if (valuesInUserCache != null) return valuesInUserCache;
+ => GetMediaStartNodePaths(user, entityService, Current.AppCaches);
- var startNodeIds = user.CalculateMediaStartNodeIds(entityService);
- var vals = entityService.GetAllPaths(UmbracoObjectTypes.Media, startNodeIds).Select(x => x.Path).ToArray();
- ToUserCache(user, cacheKey, vals);
- return vals;
+ public static string[] GetMediaStartNodePaths(this IUser user, IEntityService entityService, AppCaches appCaches)
+ {
+ var cacheKey = CacheKeys.UserMediaStartNodePathsPrefix + user.Id;
+ var runtimeCache = appCaches.IsolatedCaches.GetOrCreate();
+ var result = runtimeCache.GetCacheItem(cacheKey, () =>
+ {
+ var startNodeIds = user.CalculateMediaStartNodeIds(entityService, appCaches);
+ var vals = entityService.GetAllPaths(UmbracoObjectTypes.Media, startNodeIds).Select(x => x.Path).ToArray();
+ return vals;
+ }, TimeSpan.FromMinutes(2), true);
+
+ return result;
}
+ [Obsolete("Use the overload specifying all parameters instead")]
public static string[] GetContentStartNodePaths(this IUser user, IEntityService entityService)
+ => GetContentStartNodePaths(user, entityService, Current.AppCaches);
+
+ public static string[] GetContentStartNodePaths(this IUser user, IEntityService entityService, AppCaches appCaches)
{
- const string cacheKey = "ContentStartNodePaths";
- //try to look them up from cache so we don't recalculate
- var valuesInUserCache = FromUserCache(user, cacheKey);
- if (valuesInUserCache != null) return valuesInUserCache;
-
- var startNodeIds = user.CalculateContentStartNodeIds(entityService);
- var vals = entityService.GetAllPaths(UmbracoObjectTypes.Document, startNodeIds).Select(x => x.Path).ToArray();
- ToUserCache(user, cacheKey, vals);
- return vals;
- }
-
- private static T FromUserCache(IUser user, string cacheKey)
- where T: class
- {
- if (!(user is User entityUser)) return null;
-
- lock (entityUser.AdditionalDataLock)
+ var cacheKey = CacheKeys.UserContentStartNodePathsPrefix + user.Id;
+ var runtimeCache = appCaches.IsolatedCaches.GetOrCreate();
+ var result = runtimeCache.GetCacheItem(cacheKey, () =>
{
- return entityUser.AdditionalData.TryGetValue(cacheKey, out var allContentStartNodes)
- ? allContentStartNodes as T
- : null;
- }
- }
+ var startNodeIds = user.CalculateContentStartNodeIds(entityService, appCaches);
+ var vals = entityService.GetAllPaths(UmbracoObjectTypes.Document, startNodeIds).Select(x => x.Path).ToArray();
+ return vals;
+ }, TimeSpan.FromMinutes(2), true);
- private static void ToUserCache(IUser user, string cacheKey, T vals)
- where T: class
- {
- if (!(user is User entityUser)) return;
-
- lock (entityUser.AdditionalDataLock)
- {
- entityUser.AdditionalData[cacheKey] = vals;
- }
+ return result;
}
private static bool StartsWithPath(string test, string path)
diff --git a/src/Umbraco.Core/Security/BackOfficeUserStore.cs b/src/Umbraco.Core/Security/BackOfficeUserStore.cs
index 7df328b5b7..fe1673bca6 100644
--- a/src/Umbraco.Core/Security/BackOfficeUserStore.cs
+++ b/src/Umbraco.Core/Security/BackOfficeUserStore.cs
@@ -5,6 +5,8 @@ using System.Linq;
using System.Threading.Tasks;
using System.Web.Security;
using Microsoft.AspNet.Identity;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
@@ -38,20 +40,26 @@ namespace Umbraco.Core.Security
private readonly IExternalLoginService _externalLoginService;
private readonly IGlobalSettings _globalSettings;
private readonly UmbracoMapper _mapper;
+ private readonly AppCaches _appCaches;
private bool _disposed = false;
+ [Obsolete("Use the constructor specifying all dependencies")]
public BackOfficeUserStore(IUserService userService, IMemberTypeService memberTypeService, IEntityService entityService, IExternalLoginService externalLoginService, IGlobalSettings globalSettings, MembershipProviderBase usersMembershipProvider, UmbracoMapper mapper)
+ : this(userService, memberTypeService, entityService, externalLoginService, globalSettings, usersMembershipProvider, mapper, Current.AppCaches) { }
+
+ public BackOfficeUserStore(IUserService userService, IMemberTypeService memberTypeService, IEntityService entityService, IExternalLoginService externalLoginService, IGlobalSettings globalSettings, MembershipProviderBase usersMembershipProvider, UmbracoMapper mapper, AppCaches appCaches)
{
+ if (userService == null) throw new ArgumentNullException("userService");
+ if (usersMembershipProvider == null) throw new ArgumentNullException("usersMembershipProvider");
+ if (externalLoginService == null) throw new ArgumentNullException("externalLoginService");
+
_userService = userService;
_memberTypeService = memberTypeService;
_entityService = entityService;
_externalLoginService = externalLoginService;
- _globalSettings = globalSettings;
- if (userService == null) throw new ArgumentNullException("userService");
- if (usersMembershipProvider == null) throw new ArgumentNullException("usersMembershipProvider");
- if (externalLoginService == null) throw new ArgumentNullException("externalLoginService");
+ _globalSettings = globalSettings;
_mapper = mapper;
-
+ _appCaches = appCaches;
_userService = userService;
_externalLoginService = externalLoginService;
@@ -775,8 +783,8 @@ namespace Umbraco.Core.Security
}
//we should re-set the calculated start nodes
- identityUser.CalculatedMediaStartNodeIds = user.CalculateMediaStartNodeIds(_entityService);
- identityUser.CalculatedContentStartNodeIds = user.CalculateContentStartNodeIds(_entityService);
+ identityUser.CalculatedMediaStartNodeIds = user.CalculateMediaStartNodeIds(_entityService, _appCaches);
+ identityUser.CalculatedContentStartNodeIds = user.CalculateContentStartNodeIds(_entityService, _appCaches);
//reset all changes
identityUser.ResetDirtyProperties(false);
diff --git a/src/Umbraco.Core/Security/ContentPermissionsHelper.cs b/src/Umbraco.Core/Security/ContentPermissionsHelper.cs
index 1a329fcdcb..8c3a138f6a 100644
--- a/src/Umbraco.Core/Security/ContentPermissionsHelper.cs
+++ b/src/Umbraco.Core/Security/ContentPermissionsHelper.cs
@@ -4,6 +4,7 @@ using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Models.Membership;
@@ -25,6 +26,7 @@ namespace Umbraco.Core.Security
IUser user,
IUserService userService,
IEntityService entityService,
+ AppCaches appCaches,
params char[] permissionsToCheck)
{
if (user == null) throw new ArgumentNullException("user");
@@ -33,7 +35,7 @@ namespace Umbraco.Core.Security
if (content == null) return ContentAccess.NotFound;
- var hasPathAccess = user.HasPathAccess(content, entityService);
+ var hasPathAccess = user.HasPathAccess(content, entityService, appCaches);
if (hasPathAccess == false)
return ContentAccess.Denied;
@@ -52,6 +54,7 @@ namespace Umbraco.Core.Security
IUser user,
IUserService userService,
IEntityService entityService,
+ AppCaches appCaches,
params char[] permissionsToCheck)
{
if (user == null) throw new ArgumentNullException("user");
@@ -60,7 +63,7 @@ namespace Umbraco.Core.Security
if (entity == null) return ContentAccess.NotFound;
- var hasPathAccess = user.HasContentPathAccess(entity, entityService);
+ var hasPathAccess = user.HasContentPathAccess(entity, entityService, appCaches);
if (hasPathAccess == false)
return ContentAccess.Denied;
@@ -89,6 +92,7 @@ namespace Umbraco.Core.Security
IUser user,
IUserService userService,
IEntityService entityService,
+ AppCaches appCaches,
out IUmbracoEntity entity,
params char[] permissionsToCheck)
{
@@ -100,16 +104,16 @@ namespace Umbraco.Core.Security
entity = null;
if (nodeId == Constants.System.Root)
- hasPathAccess = user.HasContentRootAccess(entityService);
+ hasPathAccess = user.HasContentRootAccess(entityService, appCaches);
else if (nodeId == Constants.System.RecycleBinContent)
- hasPathAccess = user.HasContentBinAccess(entityService);
+ hasPathAccess = user.HasContentBinAccess(entityService, appCaches);
if (hasPathAccess.HasValue)
return hasPathAccess.Value ? ContentAccess.Granted : ContentAccess.Denied;
entity = entityService.Get(nodeId, UmbracoObjectTypes.Document);
if (entity == null) return ContentAccess.NotFound;
- hasPathAccess = user.HasContentPathAccess(entity, entityService);
+ hasPathAccess = user.HasContentPathAccess(entity, entityService, appCaches);
if (hasPathAccess == false)
return ContentAccess.Denied;
@@ -140,6 +144,7 @@ namespace Umbraco.Core.Security
IUserService userService,
IContentService contentService,
IEntityService entityService,
+ AppCaches appCaches,
out IContent contentItem,
params char[] permissionsToCheck)
{
@@ -152,16 +157,16 @@ namespace Umbraco.Core.Security
contentItem = null;
if (nodeId == Constants.System.Root)
- hasPathAccess = user.HasContentRootAccess(entityService);
+ hasPathAccess = user.HasContentRootAccess(entityService, appCaches);
else if (nodeId == Constants.System.RecycleBinContent)
- hasPathAccess = user.HasContentBinAccess(entityService);
+ hasPathAccess = user.HasContentBinAccess(entityService, appCaches);
if (hasPathAccess.HasValue)
return hasPathAccess.Value ? ContentAccess.Granted : ContentAccess.Denied;
contentItem = contentService.GetById(nodeId);
if (contentItem == null) return ContentAccess.NotFound;
- hasPathAccess = user.HasPathAccess(contentItem, entityService);
+ hasPathAccess = user.HasPathAccess(contentItem, entityService, appCaches);
if (hasPathAccess == false)
return ContentAccess.Denied;
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 080df560e4..832b8a5801 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -132,7 +132,6 @@
-
diff --git a/src/Umbraco.Tests/Models/UserExtensionsTests.cs b/src/Umbraco.Tests/Models/UserExtensionsTests.cs
index bf76031b59..18ece0c841 100644
--- a/src/Umbraco.Tests/Models/UserExtensionsTests.cs
+++ b/src/Umbraco.Tests/Models/UserExtensionsTests.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using Moq;
using NUnit.Framework;
+using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Models.Membership;
@@ -34,7 +35,7 @@ namespace Umbraco.Tests.Models
.Setup(x => x.GetAllPaths(It.IsAny(), It.IsAny()))
.Returns((type, ids) => new[] { new TreeEntityPath { Id = startNodeId, Path = startNodePath } });
- Assert.AreEqual(outcome, user.HasPathAccess(content, esmock.Object));
+ Assert.AreEqual(outcome, user.HasPathAccess(content, esmock.Object, AppCaches.Disabled));
}
[TestCase("", "1", "1")] // single user start, top level
diff --git a/src/Umbraco.Tests/Web/Controllers/ContentControllerUnitTests.cs b/src/Umbraco.Tests/Web/Controllers/ContentControllerUnitTests.cs
index f55a4e593b..26aea30c26 100644
--- a/src/Umbraco.Tests/Web/Controllers/ContentControllerUnitTests.cs
+++ b/src/Umbraco.Tests/Web/Controllers/ContentControllerUnitTests.cs
@@ -2,6 +2,7 @@
using System.Web.Http;
using Moq;
using NUnit.Framework;
+using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Models.Membership;
@@ -34,7 +35,7 @@ namespace Umbraco.Tests.Web.Controllers
var userService = userServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, out var foundContent);
+ var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent);
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Granted, result);
@@ -62,7 +63,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, out var foundContent, new[] { 'F' });
+ var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'F' });
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.NotFound, result);
@@ -93,7 +94,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, out var foundContent, new[] { 'F' });
+ var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'F' });
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Denied, result);
@@ -124,7 +125,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, out var foundContent, new[] { 'F' });
+ var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'F' });
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Denied, result);
@@ -156,7 +157,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, out var foundContent, new[] { 'F' });
+ var result = ContentPermissionsHelper.CheckPermissions(1234, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'F' });
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Granted, result);
@@ -178,7 +179,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(-1, user, userService, contentService, entityService, out var foundContent);
+ var result = ContentPermissionsHelper.CheckPermissions(-1, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent);
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Granted, result);
@@ -200,7 +201,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(-20, user, userService, contentService, entityService, out var foundContent);
+ var result = ContentPermissionsHelper.CheckPermissions(-20, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent);
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Granted, result);
@@ -224,7 +225,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(-20, user, userService, contentService, entityService, out var foundContent);
+ var result = ContentPermissionsHelper.CheckPermissions(-20, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent);
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Denied, result);
@@ -248,7 +249,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(-1, user, userService, contentService, entityService, out var foundContent);
+ var result = ContentPermissionsHelper.CheckPermissions(-1, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent);
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Denied, result);
@@ -278,7 +279,7 @@ namespace Umbraco.Tests.Web.Controllers
//act
- var result = ContentPermissionsHelper.CheckPermissions(-1, user, userService, contentService, entityService, out var foundContent, new[] { 'A' });
+ var result = ContentPermissionsHelper.CheckPermissions(-1, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'A' });
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Granted, result);
@@ -306,7 +307,7 @@ namespace Umbraco.Tests.Web.Controllers
var contentService = contentServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(-1, user, userService, contentService, entityService, out var foundContent, new[] { 'B' });
+ var result = ContentPermissionsHelper.CheckPermissions(-1, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'B' });
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Denied, result);
@@ -336,7 +337,7 @@ namespace Umbraco.Tests.Web.Controllers
var contentService = contentServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(-20, user, userService, contentService, entityService, out var foundContent, new[] { 'A' });
+ var result = ContentPermissionsHelper.CheckPermissions(-20, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'A' });
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Granted, result);
@@ -364,7 +365,7 @@ namespace Umbraco.Tests.Web.Controllers
var contentService = contentServiceMock.Object;
//act
- var result = ContentPermissionsHelper.CheckPermissions(-20, user, userService, contentService, entityService, out var foundContent, new[] { 'B' });
+ var result = ContentPermissionsHelper.CheckPermissions(-20, user, userService, contentService, entityService, AppCaches.Disabled, out var foundContent, new[] { 'B' });
//assert
Assert.AreEqual(ContentPermissionsHelper.ContentAccess.Denied, result);
diff --git a/src/Umbraco.Tests/Web/Controllers/FilterAllowedOutgoingContentAttributeTests.cs b/src/Umbraco.Tests/Web/Controllers/FilterAllowedOutgoingContentAttributeTests.cs
index 634d58b3fd..4f1beb6e8d 100644
--- a/src/Umbraco.Tests/Web/Controllers/FilterAllowedOutgoingContentAttributeTests.cs
+++ b/src/Umbraco.Tests/Web/Controllers/FilterAllowedOutgoingContentAttributeTests.cs
@@ -6,6 +6,8 @@ using System.Net.Http.Headers;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Composing;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Models.Membership;
@@ -26,7 +28,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityServiceMock = new Mock();
var entityService = entityServiceMock.Object;
- var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), userService, entityService);
+ var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), userService, entityService, AppCaches.Disabled);
var val = new List() {new ContentItemBasic()};
var result = att.GetValueFromResponse(
new ObjectContent(typeof (IEnumerable),
@@ -46,7 +48,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityServiceMock = new Mock();
var entityService = entityServiceMock.Object;
- var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), "MyList", userService, entityService);
+ var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), "MyList", userService, entityService, AppCaches.Disabled);
var val = new List() { new ContentItemBasic() };
var container = new MyTestClass() {MyList = val};
@@ -68,7 +70,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityServiceMock = new Mock();
var entityService = entityServiceMock.Object;
- var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), "DontFind", userService, entityService);
+ var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), "DontFind", userService, entityService, AppCaches.Disabled);
var val = new List() { new ContentItemBasic() };
var container = new MyTestClass() { MyList = val };
@@ -96,7 +98,7 @@ namespace Umbraco.Tests.Web.Controllers
.Returns(new[] { Mock.Of(entity => entity.Id == 5 && entity.Path == "-1,5") });
var entityService = entityServiceMock.Object;
- var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), userService, entityService);
+ var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), userService, entityService, AppCaches.Disabled);
var list = new List();
var path = "";
for (var i = 0; i < 10; i++)
@@ -144,7 +146,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityServiceMock = new Mock();
var entityService = entityServiceMock.Object;
- var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), userService, entityService);
+ var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), userService, entityService, AppCaches.Disabled);
att.FilterBasedOnPermissions(list, user);
Assert.AreEqual(3, list.Count);
diff --git a/src/Umbraco.Tests/Web/Controllers/MediaControllerUnitTests.cs b/src/Umbraco.Tests/Web/Controllers/MediaControllerUnitTests.cs
index f409d81a2d..c347d81288 100644
--- a/src/Umbraco.Tests/Web/Controllers/MediaControllerUnitTests.cs
+++ b/src/Umbraco.Tests/Web/Controllers/MediaControllerUnitTests.cs
@@ -2,6 +2,7 @@
using System.Web.Http;
using Moq;
using NUnit.Framework;
+using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Models.Membership;
@@ -31,7 +32,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, 1234);
+ var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, AppCaches.Disabled, 1234);
//assert
Assert.IsTrue(result);
@@ -54,7 +55,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act/assert
- Assert.Throws(() => MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, 1234));
+ Assert.Throws(() => MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, AppCaches.Disabled, 1234));
}
[Test]
@@ -77,7 +78,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, 1234);
+ var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, AppCaches.Disabled, 1234);
//assert
Assert.IsFalse(result);
@@ -97,7 +98,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, -1);
+ var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, AppCaches.Disabled, -1);
//assert
Assert.IsTrue(result);
@@ -119,7 +120,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, -1);
+ var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, AppCaches.Disabled, -1);
//assert
Assert.IsFalse(result);
@@ -139,7 +140,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, -21);
+ var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, AppCaches.Disabled, -21);
//assert
Assert.IsTrue(result);
@@ -161,7 +162,7 @@ namespace Umbraco.Tests.Web.Controllers
var entityService = entityServiceMock.Object;
//act
- var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, -21);
+ var result = MediaController.CheckPermissions(new Dictionary(), user, mediaService, entityService, AppCaches.Disabled, -21);
//assert
Assert.IsFalse(result);
diff --git a/src/Umbraco.Tests/Web/Controllers/UserEditorAuthorizationHelperTests.cs b/src/Umbraco.Tests/Web/Controllers/UserEditorAuthorizationHelperTests.cs
index 04694b21ee..4478b59085 100644
--- a/src/Umbraco.Tests/Web/Controllers/UserEditorAuthorizationHelperTests.cs
+++ b/src/Umbraco.Tests/Web/Controllers/UserEditorAuthorizationHelperTests.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
+using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Models.Membership;
@@ -32,7 +33,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
var result = authHelper.IsAuthorized(currentUser, savingUser, new int[0], new int[0], new string[0]);
@@ -54,7 +56,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
var result = authHelper.IsAuthorized(currentUser, savingUser, new int[0], new int[0], new string[0]);
@@ -79,7 +82,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
var result = authHelper.IsAuthorized(currentUser, savingUser, new int[0], new int[0], new[] {"FunGroup"});
@@ -104,7 +108,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
var result = authHelper.IsAuthorized(currentUser, savingUser, new int[0], new int[0], new[] { "test" });
@@ -141,7 +146,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
//adding 5555 which currentUser has access to since it's a child of 9876 ... adding is still ok even though currentUser doesn't have access to 1234
var result = authHelper.IsAuthorized(currentUser, savingUser, new[] { 1234, 5555 }, new int[0], new string[0]);
@@ -179,7 +185,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
//removing 4567 start node even though currentUser doesn't have acces to it ... removing is ok
var result = authHelper.IsAuthorized(currentUser, savingUser, new[] { 1234 }, new int[0], new string[0]);
@@ -217,7 +224,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
//adding 1234 but currentUser doesn't have access to it ... nope
var result = authHelper.IsAuthorized(currentUser, savingUser, new []{1234}, new int[0], new string[0]);
@@ -255,7 +263,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
//adding 5555 which currentUser has access to since it's a child of 9876 ... ok
var result = authHelper.IsAuthorized(currentUser, savingUser, new[] { 5555 }, new int[0], new string[0]);
@@ -293,7 +302,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
//adding 1234 but currentUser doesn't have access to it ... nope
var result = authHelper.IsAuthorized(currentUser, savingUser, new int[0], new[] {1234}, new string[0]);
@@ -331,7 +341,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
//adding 5555 which currentUser has access to since it's a child of 9876 ... ok
var result = authHelper.IsAuthorized(currentUser, savingUser, new int[0], new[] { 5555 }, new string[0]);
@@ -369,7 +380,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
//adding 5555 which currentUser has access to since it's a child of 9876 ... adding is still ok even though currentUser doesn't have access to 1234
var result = authHelper.IsAuthorized(currentUser, savingUser, new int[0], new[] { 1234, 5555 }, new string[0]);
@@ -407,7 +419,8 @@ namespace Umbraco.Tests.Web.Controllers
contentService.Object,
mediaService.Object,
userService.Object,
- entityService.Object);
+ entityService.Object,
+ AppCaches.Disabled);
//removing 4567 start node even though currentUser doesn't have acces to it ... removing is ok
var result = authHelper.IsAuthorized(currentUser, savingUser, new int[0], new[] { 1234 }, new string[0]);
diff --git a/src/Umbraco.Web/Cache/UserCacheRefresher.cs b/src/Umbraco.Web/Cache/UserCacheRefresher.cs
index 922a9df385..ce2cbbf754 100644
--- a/src/Umbraco.Web/Cache/UserCacheRefresher.cs
+++ b/src/Umbraco.Web/Cache/UserCacheRefresher.cs
@@ -42,7 +42,14 @@ namespace Umbraco.Web.Cache
{
var userCache = AppCaches.IsolatedCaches.Get();
if (userCache)
+ {
userCache.Result.Clear(RepositoryCacheKeys.GetKey(id));
+ userCache.Result.ClearByKey(CacheKeys.UserContentStartNodePathsPrefix + id);
+ userCache.Result.ClearByKey(CacheKeys.UserMediaStartNodePathsPrefix + id);
+ userCache.Result.ClearByKey(CacheKeys.UserAllContentStartNodesPrefix + id);
+ userCache.Result.ClearByKey(CacheKeys.UserAllMediaStartNodesPrefix + id);
+ }
+
base.Remove(id);
}
diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs
index 6f85a08751..7093edf23d 100644
--- a/src/Umbraco.Web/Editors/ContentController.cs
+++ b/src/Umbraco.Web/Editors/ContentController.cs
@@ -1168,7 +1168,7 @@ namespace Umbraco.Web.Editors
//if this item's path has already been denied or if the user doesn't have access to it, add to the deny list
if (denied.Any(x => c.Path.StartsWith($"{x.Path},"))
|| (ContentPermissionsHelper.CheckPermissions(c,
- Security.CurrentUser, Services.UserService, Services.EntityService,
+ Security.CurrentUser, Services.UserService, Services.EntityService, AppCaches,
ActionPublish.ActionLetter) == ContentPermissionsHelper.ContentAccess.Denied))
{
denied.Add(c);
diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs
index fe78b29123..9399deb1e5 100644
--- a/src/Umbraco.Web/Editors/EntityController.cs
+++ b/src/Umbraco.Web/Editors/EntityController.cs
@@ -670,9 +670,9 @@ namespace Umbraco.Web.Editors
switch (type)
{
case UmbracoEntityTypes.Document:
- return Security.CurrentUser.CalculateContentStartNodeIds(Services.EntityService);
+ return Security.CurrentUser.CalculateContentStartNodeIds(Services.EntityService, AppCaches);
case UmbracoEntityTypes.Media:
- return Security.CurrentUser.CalculateMediaStartNodeIds(Services.EntityService);
+ return Security.CurrentUser.CalculateMediaStartNodeIds(Services.EntityService, AppCaches);
default:
return Array.Empty();
}
@@ -811,10 +811,10 @@ namespace Umbraco.Web.Editors
switch (entityType)
{
case UmbracoEntityTypes.Document:
- aids = Security.CurrentUser.CalculateContentStartNodeIds(Services.EntityService);
+ aids = Security.CurrentUser.CalculateContentStartNodeIds(Services.EntityService, AppCaches);
break;
case UmbracoEntityTypes.Media:
- aids = Security.CurrentUser.CalculateMediaStartNodeIds(Services.EntityService);
+ aids = Security.CurrentUser.CalculateMediaStartNodeIds(Services.EntityService, AppCaches);
break;
}
diff --git a/src/Umbraco.Web/Editors/Filters/ContentSaveValidationAttribute.cs b/src/Umbraco.Web/Editors/Filters/ContentSaveValidationAttribute.cs
index fbce2d0414..c0e190989a 100644
--- a/src/Umbraco.Web/Editors/Filters/ContentSaveValidationAttribute.cs
+++ b/src/Umbraco.Web/Editors/Filters/ContentSaveValidationAttribute.cs
@@ -7,6 +7,7 @@ using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Umbraco.Core;
+using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Security;
@@ -29,11 +30,12 @@ namespace Umbraco.Web.Editors.Filters
private readonly IContentService _contentService;
private readonly IUserService _userService;
private readonly IEntityService _entityService;
+ private readonly AppCaches _appCaches;
- public ContentSaveValidationAttribute(): this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.ContentService, Current.Services.UserService, Current.Services.EntityService)
+ public ContentSaveValidationAttribute(): this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.ContentService, Current.Services.UserService, Current.Services.EntityService, Current.AppCaches)
{ }
- public ContentSaveValidationAttribute(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService textService, IContentService contentService, IUserService userService, IEntityService entityService)
+ public ContentSaveValidationAttribute(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService textService, IContentService contentService, IUserService userService, IEntityService entityService, AppCaches appCaches)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
@@ -41,6 +43,7 @@ namespace Umbraco.Web.Editors.Filters
_contentService = contentService ?? throw new ArgumentNullException(nameof(contentService));
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
_entityService = entityService ?? throw new ArgumentNullException(nameof(entityService));
+ _appCaches = appCaches;
}
public override void OnActionExecuting(HttpActionContext actionContext)
@@ -195,13 +198,13 @@ namespace Umbraco.Web.Editors.Filters
accessResult = ContentPermissionsHelper.CheckPermissions(
contentToCheck, webSecurity.CurrentUser,
- _userService, _entityService, permissionToCheck.ToArray());
+ _userService, _entityService, _appCaches, permissionToCheck.ToArray());
}
else
{
accessResult = ContentPermissionsHelper.CheckPermissions(
contentIdToCheck, webSecurity.CurrentUser,
- _userService, _contentService, _entityService,
+ _userService, _contentService, _entityService, _appCaches,
out contentToCheck,
permissionToCheck.ToArray());
if (contentToCheck != null)
diff --git a/src/Umbraco.Web/Editors/Filters/MediaItemSaveValidationAttribute.cs b/src/Umbraco.Web/Editors/Filters/MediaItemSaveValidationAttribute.cs
index 449ef95675..af973d0662 100644
--- a/src/Umbraco.Web/Editors/Filters/MediaItemSaveValidationAttribute.cs
+++ b/src/Umbraco.Web/Editors/Filters/MediaItemSaveValidationAttribute.cs
@@ -4,6 +4,7 @@ using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Umbraco.Core;
+using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
@@ -23,18 +24,20 @@ namespace Umbraco.Web.Editors.Filters
private readonly ILocalizedTextService _textService;
private readonly IMediaService _mediaService;
private readonly IEntityService _entityService;
+ private readonly AppCaches _appCaches;
- public MediaItemSaveValidationAttribute() : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.MediaService, Current.Services.EntityService)
+ public MediaItemSaveValidationAttribute() : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.MediaService, Current.Services.EntityService, Current.AppCaches)
{
}
- public MediaItemSaveValidationAttribute(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService textService, IMediaService mediaService, IEntityService entityService)
+ public MediaItemSaveValidationAttribute(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService textService, IMediaService mediaService, IEntityService entityService, AppCaches appCaches)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
_textService = textService ?? throw new ArgumentNullException(nameof(textService));
_mediaService = mediaService ?? throw new ArgumentNullException(nameof(mediaService));
_entityService = entityService ?? throw new ArgumentNullException(nameof(entityService));
+ _appCaches = appCaches;
}
public override void OnActionExecuting(HttpActionContext actionContext)
@@ -91,7 +94,7 @@ namespace Umbraco.Web.Editors.Filters
if (MediaController.CheckPermissions(
actionContext.Request.Properties,
_umbracoContextAccessor.UmbracoContext.Security.CurrentUser,
- _mediaService, _entityService,
+ _mediaService, _entityService, _appCaches,
contentIdToCheck, contentToCheck) == false)
{
actionContext.Response = actionContext.Request.CreateUserNoAccessResponse();
diff --git a/src/Umbraco.Web/Editors/Filters/UserGroupAuthorizationAttribute.cs b/src/Umbraco.Web/Editors/Filters/UserGroupAuthorizationAttribute.cs
index e1d6626055..e94098db82 100644
--- a/src/Umbraco.Web/Editors/Filters/UserGroupAuthorizationAttribute.cs
+++ b/src/Umbraco.Web/Editors/Filters/UserGroupAuthorizationAttribute.cs
@@ -54,7 +54,8 @@ namespace Umbraco.Web.Editors.Filters
Current.Services.UserService,
Current.Services.ContentService,
Current.Services.MediaService,
- Current.Services.EntityService);
+ Current.Services.EntityService,
+ Current.AppCaches);
return authHelper.AuthorizeGroupAccess(currentUser, intIds);
}
}
diff --git a/src/Umbraco.Web/Editors/Filters/UserGroupEditorAuthorizationHelper.cs b/src/Umbraco.Web/Editors/Filters/UserGroupEditorAuthorizationHelper.cs
index 985c42bbbf..ea403758d0 100644
--- a/src/Umbraco.Web/Editors/Filters/UserGroupEditorAuthorizationHelper.cs
+++ b/src/Umbraco.Web/Editors/Filters/UserGroupEditorAuthorizationHelper.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
+using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
@@ -13,13 +14,15 @@ namespace Umbraco.Web.Editors.Filters
private readonly IContentService _contentService;
private readonly IMediaService _mediaService;
private readonly IEntityService _entityService;
+ private readonly AppCaches _appCaches;
- public UserGroupEditorAuthorizationHelper(IUserService userService, IContentService contentService, IMediaService mediaService, IEntityService entityService)
+ public UserGroupEditorAuthorizationHelper(IUserService userService, IContentService contentService, IMediaService mediaService, IEntityService entityService, AppCaches appCaches)
{
_userService = userService;
_contentService = contentService;
_mediaService = mediaService;
_entityService = entityService;
+ _appCaches = appCaches;
}
///
@@ -111,7 +114,7 @@ namespace Umbraco.Web.Editors.Filters
var content = _contentService.GetById(proposedContentStartId.Value);
if (content != null)
{
- if (currentUser.HasPathAccess(content, _entityService) == false)
+ if (currentUser.HasPathAccess(content, _entityService, _appCaches) == false)
return Attempt.Fail("Current user doesn't have access to the content path " + content.Path);
}
}
@@ -121,7 +124,7 @@ namespace Umbraco.Web.Editors.Filters
var media = _mediaService.GetById(proposedMediaStartId.Value);
if (media != null)
{
- if (currentUser.HasPathAccess(media, _entityService) == false)
+ if (currentUser.HasPathAccess(media, _entityService, _appCaches) == false)
return Attempt.Fail("Current user doesn't have access to the media path " + media.Path);
}
}
diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs
index 5fd59d0c9f..8d13ccd4d7 100644
--- a/src/Umbraco.Web/Editors/MediaController.cs
+++ b/src/Umbraco.Web/Editors/MediaController.cs
@@ -239,7 +239,7 @@ namespace Umbraco.Web.Editors
protected int[] UserStartNodes
{
- get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.CalculateMediaStartNodeIds(Services.EntityService)); }
+ get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.CalculateMediaStartNodeIds(Services.EntityService, AppCaches)); }
}
///
@@ -835,6 +835,7 @@ namespace Umbraco.Web.Editors
Security.CurrentUser,
Services.MediaService,
Services.EntityService,
+ AppCaches,
intParentId) == false)
{
throw new HttpResponseException(Request.CreateResponse(
@@ -919,7 +920,7 @@ namespace Umbraco.Web.Editors
/// The content to lookup, if the contentItem is not specified
/// Specifies the already resolved content item to check against, setting this ignores the nodeId
///
- internal static bool CheckPermissions(IDictionary storage, IUser user, IMediaService mediaService, IEntityService entityService, int nodeId, IMedia media = null)
+ internal static bool CheckPermissions(IDictionary storage, IUser user, IMediaService mediaService, IEntityService entityService, AppCaches appCaches, int nodeId, IMedia media = null)
{
if (storage == null) throw new ArgumentNullException("storage");
if (user == null) throw new ArgumentNullException("user");
@@ -940,10 +941,10 @@ namespace Umbraco.Web.Editors
}
var hasPathAccess = (nodeId == Constants.System.Root)
- ? user.HasMediaRootAccess(entityService)
+ ? user.HasMediaRootAccess(entityService, appCaches)
: (nodeId == Constants.System.RecycleBinMedia)
- ? user.HasMediaBinAccess(entityService)
- : user.HasPathAccess(media, entityService);
+ ? user.HasMediaBinAccess(entityService, appCaches)
+ : user.HasPathAccess(media, entityService, appCaches);
return hasPathAccess;
}
diff --git a/src/Umbraco.Web/Editors/UserEditorAuthorizationHelper.cs b/src/Umbraco.Web/Editors/UserEditorAuthorizationHelper.cs
index 320580aaf9..f666b6d5a3 100644
--- a/src/Umbraco.Web/Editors/UserEditorAuthorizationHelper.cs
+++ b/src/Umbraco.Web/Editors/UserEditorAuthorizationHelper.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
+using Umbraco.Core.Cache;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Security;
@@ -14,13 +15,15 @@ namespace Umbraco.Web.Editors
private readonly IMediaService _mediaService;
private readonly IUserService _userService;
private readonly IEntityService _entityService;
+ private readonly AppCaches _appCaches;
- public UserEditorAuthorizationHelper(IContentService contentService, IMediaService mediaService, IUserService userService, IEntityService entityService)
+ public UserEditorAuthorizationHelper(IContentService contentService, IMediaService mediaService, IUserService userService, IEntityService entityService, AppCaches appCaches)
{
_contentService = contentService;
_mediaService = mediaService;
_userService = userService;
_entityService = entityService;
+ _appCaches = appCaches;
}
///
@@ -114,7 +117,7 @@ namespace Umbraco.Web.Editors
{
if (contentId == Constants.System.Root)
{
- var hasAccess = ContentPermissionsHelper.HasPathAccess("-1", currentUser.CalculateContentStartNodeIds(_entityService), Constants.System.RecycleBinContent);
+ var hasAccess = ContentPermissionsHelper.HasPathAccess("-1", currentUser.CalculateContentStartNodeIds(_entityService, _appCaches), Constants.System.RecycleBinContent);
if (hasAccess == false)
return Attempt.Fail("The current user does not have access to the content root");
}
@@ -122,7 +125,7 @@ namespace Umbraco.Web.Editors
{
var content = _contentService.GetById(contentId);
if (content == null) continue;
- var hasAccess = currentUser.HasPathAccess(content, _entityService);
+ var hasAccess = currentUser.HasPathAccess(content, _entityService, _appCaches);
if (hasAccess == false)
return Attempt.Fail("The current user does not have access to the content path " + content.Path);
}
@@ -135,7 +138,7 @@ namespace Umbraco.Web.Editors
{
if (mediaId == Constants.System.Root)
{
- var hasAccess = ContentPermissionsHelper.HasPathAccess("-1", currentUser.CalculateMediaStartNodeIds(_entityService), Constants.System.RecycleBinMedia);
+ var hasAccess = ContentPermissionsHelper.HasPathAccess("-1", currentUser.CalculateMediaStartNodeIds(_entityService, _appCaches), Constants.System.RecycleBinMedia);
if (hasAccess == false)
return Attempt.Fail("The current user does not have access to the media root");
}
@@ -143,7 +146,7 @@ namespace Umbraco.Web.Editors
{
var media = _mediaService.GetById(mediaId);
if (media == null) continue;
- var hasAccess = currentUser.HasPathAccess(media, _entityService);
+ var hasAccess = currentUser.HasPathAccess(media, _entityService, _appCaches);
if (hasAccess == false)
return Attempt.Fail("The current user does not have access to the media path " + media.Path);
}
diff --git a/src/Umbraco.Web/Editors/UserGroupsController.cs b/src/Umbraco.Web/Editors/UserGroupsController.cs
index b081ca6137..77f7a305af 100644
--- a/src/Umbraco.Web/Editors/UserGroupsController.cs
+++ b/src/Umbraco.Web/Editors/UserGroupsController.cs
@@ -28,7 +28,11 @@ namespace Umbraco.Web.Editors
//authorize that the user has access to save this user group
var authHelper = new UserGroupEditorAuthorizationHelper(
- Services.UserService, Services.ContentService, Services.MediaService, Services.EntityService);
+ Services.UserService,
+ Services.ContentService,
+ Services.MediaService,
+ Services.EntityService,
+ AppCaches);
var isAuthorized = authHelper.AuthorizeGroupAccess(Security.CurrentUser, userGroupSave.Alias);
if (isAuthorized == false)
diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs
index 3f29203819..e8bc33cc26 100644
--- a/src/Umbraco.Web/Editors/UsersController.cs
+++ b/src/Umbraco.Web/Editors/UsersController.cs
@@ -304,7 +304,7 @@ namespace Umbraco.Web.Editors
CheckUniqueEmail(userSave.Email, null);
//Perform authorization here to see if the current user can actually save this user with the info being requested
- var authHelper = new UserEditorAuthorizationHelper(Services.ContentService, Services.MediaService, Services.UserService, Services.EntityService);
+ var authHelper = new UserEditorAuthorizationHelper(Services.ContentService, Services.MediaService, Services.UserService, Services.EntityService, AppCaches);
var canSaveUser = authHelper.IsAuthorized(Security.CurrentUser, null, null, null, userSave.UserGroups);
if (canSaveUser == false)
{
@@ -398,7 +398,7 @@ namespace Umbraco.Web.Editors
}
//Perform authorization here to see if the current user can actually save this user with the info being requested
- var authHelper = new UserEditorAuthorizationHelper(Services.ContentService, Services.MediaService, Services.UserService, Services.EntityService);
+ var authHelper = new UserEditorAuthorizationHelper(Services.ContentService, Services.MediaService, Services.UserService, Services.EntityService, AppCaches);
var canSaveUser = authHelper.IsAuthorized(Security.CurrentUser, user, null, null, userSave.UserGroups);
if (canSaveUser == false)
{
@@ -573,7 +573,7 @@ namespace Umbraco.Web.Editors
throw new HttpResponseException(HttpStatusCode.NotFound);
//Perform authorization here to see if the current user can actually save this user with the info being requested
- var authHelper = new UserEditorAuthorizationHelper(Services.ContentService, Services.MediaService, Services.UserService, Services.EntityService);
+ var authHelper = new UserEditorAuthorizationHelper(Services.ContentService, Services.MediaService, Services.UserService, Services.EntityService, AppCaches);
var canSaveUser = authHelper.IsAuthorized(Security.CurrentUser, found, userSave.StartContentIds, userSave.StartMediaIds, userSave.UserGroups);
if (canSaveUser == false)
{
diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs
index 16465914cb..0360ee568b 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs
@@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
@@ -29,14 +31,25 @@ namespace Umbraco.Web.Models.Mapping
private readonly ILogger _logger;
private readonly IUserService _userService;
private readonly IEntityService _entityService;
+ private readonly AppCaches _appCaches;
private readonly TabsAndPropertiesMapper _tabsAndPropertiesMapper;
private readonly ContentSavedStateMapper _stateMapper;
private readonly ContentBasicSavedStateMapper _basicStateMapper;
private readonly ContentVariantMapper _contentVariantMapper;
- public ContentMapDefinition(CommonMapper commonMapper, ILocalizedTextService localizedTextService, IContentService contentService, IContentTypeService contentTypeService,
- IFileService fileService, IUmbracoContextAccessor umbracoContextAccessor, IPublishedRouter publishedRouter, ILocalizationService localizationService, ILogger logger,
- IUserService userService, IEntityService entityService)
+ public ContentMapDefinition(
+ CommonMapper commonMapper,
+ ILocalizedTextService localizedTextService,
+ IContentService contentService,
+ IContentTypeService contentTypeService,
+ IFileService fileService,
+ IUmbracoContextAccessor umbracoContextAccessor,
+ IPublishedRouter publishedRouter,
+ ILocalizationService localizationService,
+ ILogger logger,
+ IUserService userService,
+ IEntityService entityService,
+ AppCaches appCaches)
{
_commonMapper = commonMapper;
_localizedTextService = localizedTextService;
@@ -49,6 +62,7 @@ namespace Umbraco.Web.Models.Mapping
_logger = logger;
_userService = userService;
_entityService = entityService;
+ _appCaches = appCaches;
_tabsAndPropertiesMapper = new TabsAndPropertiesMapper(localizedTextService);
_stateMapper = new ContentSavedStateMapper();
_basicStateMapper = new ContentBasicSavedStateMapper();
@@ -238,7 +252,7 @@ namespace Umbraco.Web.Models.Mapping
// false here.
if (context.HasItems && context.Items.TryGetValue("CurrentUser", out var usr) && usr is IUser currentUser)
{
- userStartNodes = currentUser.CalculateContentStartNodeIds(_entityService);
+ userStartNodes = currentUser.CalculateContentStartNodeIds(_entityService, _appCaches);
if (!userStartNodes.Contains(Constants.System.Root))
{
// return false if this is the user's actual start node, the node will be rendered in the tree
diff --git a/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs
index aa158799cb..6c58309f57 100644
--- a/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs
+++ b/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs
@@ -273,8 +273,8 @@ namespace Umbraco.Web.Models.Mapping
{
target.AvailableCultures = _textService.GetSupportedCultures().ToDictionary(x => x.Name, x => x.DisplayName);
target.Avatars = source.GetUserAvatarUrls(_appCaches.RuntimeCache);
- target.CalculatedStartContentIds = GetStartNodes(source.CalculateContentStartNodeIds(_entityService), UmbracoObjectTypes.Document, "content/contentRoot", context);
- target.CalculatedStartMediaIds = GetStartNodes(source.CalculateMediaStartNodeIds(_entityService), UmbracoObjectTypes.Media, "media/mediaRoot", context);
+ target.CalculatedStartContentIds = GetStartNodes(source.CalculateContentStartNodeIds(_entityService, _appCaches), UmbracoObjectTypes.Document, "content/contentRoot", context);
+ target.CalculatedStartMediaIds = GetStartNodes(source.CalculateMediaStartNodeIds(_entityService, _appCaches), UmbracoObjectTypes.Media, "media/mediaRoot", context);
target.CreateDate = source.CreateDate;
target.Culture = source.GetUserCulture(_textService, _globalSettings).ToString();
target.Email = source.Email;
@@ -327,8 +327,8 @@ namespace Umbraco.Web.Models.Mapping
target.Email = source.Email;
target.EmailHash = source.Email.ToLowerInvariant().Trim().GenerateHash();
target.Name = source.Name;
- target.StartContentIds = source.CalculateContentStartNodeIds(_entityService);
- target.StartMediaIds = source.CalculateMediaStartNodeIds(_entityService);
+ target.StartContentIds = source.CalculateContentStartNodeIds(_entityService, _appCaches);
+ target.StartMediaIds = source.CalculateMediaStartNodeIds(_entityService, _appCaches);
target.UserId = source.Id;
//we need to map the legacy UserType
diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
index 410b654e32..134d482b40 100644
--- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
+++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
@@ -5,6 +5,8 @@ using System.Text;
using System.Text.RegularExpressions;
using Examine;
using Umbraco.Core;
+using Umbraco.Core.Cache;
+using Umbraco.Core.Composing;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
@@ -30,14 +32,29 @@ namespace Umbraco.Web.Search
private readonly UmbracoMapper _mapper;
private readonly ISqlContext _sqlContext;
private readonly IUmbracoTreeSearcherFields _umbracoTreeSearcherFields;
+ private readonly AppCaches _appCaches;
-
- public UmbracoTreeSearcher(IExamineManager examineManager,
+ [Obsolete("Use constructor specifying all dependencies instead")]
+ public UmbracoTreeSearcher(
+ IExamineManager examineManager,
UmbracoContext umbracoContext,
ILocalizationService languageService,
IEntityService entityService,
UmbracoMapper mapper,
- ISqlContext sqlContext,IUmbracoTreeSearcherFields umbracoTreeSearcherFields)
+ ISqlContext sqlContext,
+ IUmbracoTreeSearcherFields umbracoTreeSearcherFields)
+ : this(examineManager, umbracoContext, languageService, entityService, mapper, sqlContext, umbracoTreeSearcherFields, Current.AppCaches)
+ { }
+
+ public UmbracoTreeSearcher(
+ IExamineManager examineManager,
+ UmbracoContext umbracoContext,
+ ILocalizationService languageService,
+ IEntityService entityService,
+ UmbracoMapper mapper,
+ ISqlContext sqlContext,
+ IUmbracoTreeSearcherFields umbracoTreeSearcherFields,
+ AppCaches appCaches)
{
_examineManager = examineManager ?? throw new ArgumentNullException(nameof(examineManager));
_umbracoContext = umbracoContext;
@@ -46,6 +63,7 @@ namespace Umbraco.Web.Search
_mapper = mapper;
_sqlContext = sqlContext;
_umbracoTreeSearcherFields = umbracoTreeSearcherFields;
+ _appCaches = appCaches;
}
///
@@ -112,13 +130,13 @@ namespace Umbraco.Web.Search
case UmbracoEntityTypes.Media:
type = "media";
fields.AddRange(_umbracoTreeSearcherFields.GetBackOfficeMediaFields());
- var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService);
+ var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService, _appCaches);
AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService);
break;
case UmbracoEntityTypes.Document:
type = "content";
fields.AddRange(_umbracoTreeSearcherFields.GetBackOfficeDocumentFields());
- var allContentStartNodes = _umbracoContext.Security.CurrentUser.CalculateContentStartNodeIds(_entityService);
+ var allContentStartNodes = _umbracoContext.Security.CurrentUser.CalculateContentStartNodeIds(_entityService, _appCaches);
AppendPath(sb, UmbracoObjectTypes.Document, allContentStartNodes, searchFrom, ignoreUserStartNodes, _entityService);
break;
default:
@@ -462,11 +480,13 @@ namespace Umbraco.Web.Search
var defaultLang = _languageService.GetDefaultLanguageIsoCode();
foreach (var result in results)
{
- var entity = _mapper.Map(result, context => {
- if(culture != null) {
- context.SetCulture(culture);
- }
+ var entity = _mapper.Map(result, context =>
+ {
+ if (culture != null)
+ {
+ context.SetCulture(culture);
}
+ }
);
var intId = entity.Id.TryConvertTo();
diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs
index ead265e7c5..d82166b9a3 100644
--- a/src/Umbraco.Web/Trees/ContentTreeController.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeController.cs
@@ -47,7 +47,7 @@ namespace Umbraco.Web.Trees
private int[] _userStartNodes;
protected override int[] UserStartNodes
- => _userStartNodes ?? (_userStartNodes = Security.CurrentUser.CalculateContentStartNodeIds(Services.EntityService));
+ => _userStartNodes ?? (_userStartNodes = Security.CurrentUser.CalculateContentStartNodeIds(Services.EntityService, AppCaches));
public ContentTreeController(UmbracoTreeSearcher treeSearcher, ActionCollection actions, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
{
@@ -165,7 +165,7 @@ namespace Umbraco.Web.Trees
}
//if the user has no path access for this node, all they can do is refresh
- if (!Security.CurrentUser.HasContentPathAccess(item, Services.EntityService))
+ if (!Security.CurrentUser.HasContentPathAccess(item, Services.EntityService, AppCaches))
{
var menu = new MenuItemCollection();
menu.Items.Add(new RefreshNode(Services.TextService, true));
diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
index e9c34608a2..57c7027598 100644
--- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
@@ -126,12 +126,12 @@ namespace Umbraco.Web.Trees
switch (RecycleBinId)
{
case Constants.System.RecycleBinMedia:
- startNodeIds = Security.CurrentUser.CalculateMediaStartNodeIds(Services.EntityService);
- startNodePaths = Security.CurrentUser.GetMediaStartNodePaths(Services.EntityService);
+ startNodeIds = Security.CurrentUser.CalculateMediaStartNodeIds(Services.EntityService, AppCaches);
+ startNodePaths = Security.CurrentUser.GetMediaStartNodePaths(Services.EntityService, AppCaches);
break;
case Constants.System.RecycleBinContent:
- startNodeIds = Security.CurrentUser.CalculateContentStartNodeIds(Services.EntityService);
- startNodePaths = Security.CurrentUser.GetContentStartNodePaths(Services.EntityService);
+ startNodeIds = Security.CurrentUser.CalculateContentStartNodeIds(Services.EntityService, AppCaches);
+ startNodePaths = Security.CurrentUser.GetContentStartNodePaths(Services.EntityService, AppCaches);
break;
default:
throw new NotSupportedException("Path access is only determined on content or media");
@@ -291,8 +291,8 @@ namespace Umbraco.Web.Trees
{
if (entity == null) return false;
return RecycleBinId == Constants.System.RecycleBinContent
- ? Security.CurrentUser.HasContentPathAccess(entity, Services.EntityService)
- : Security.CurrentUser.HasMediaPathAccess(entity, Services.EntityService);
+ ? Security.CurrentUser.HasContentPathAccess(entity, Services.EntityService, AppCaches)
+ : Security.CurrentUser.HasMediaPathAccess(entity, Services.EntityService, AppCaches);
}
///
diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs
index cc71b92d15..43b5a83282 100644
--- a/src/Umbraco.Web/Trees/MediaTreeController.cs
+++ b/src/Umbraco.Web/Trees/MediaTreeController.cs
@@ -50,7 +50,7 @@ namespace Umbraco.Web.Trees
private int[] _userStartNodes;
protected override int[] UserStartNodes
- => _userStartNodes ?? (_userStartNodes = Security.CurrentUser.CalculateMediaStartNodeIds(Services.EntityService));
+ => _userStartNodes ?? (_userStartNodes = Security.CurrentUser.CalculateMediaStartNodeIds(Services.EntityService, AppCaches));
///
/// Creates a tree node for a content item based on an UmbracoEntity
@@ -117,7 +117,7 @@ namespace Umbraco.Web.Trees
}
//if the user has no path access for this node, all they can do is refresh
- if (!Security.CurrentUser.HasMediaPathAccess(item, Services.EntityService))
+ if (!Security.CurrentUser.HasMediaPathAccess(item, Services.EntityService, AppCaches))
{
menu.Items.Add(new RefreshNode(Services.TextService, true));
return menu;
diff --git a/src/Umbraco.Web/WebApi/Filters/AdminUsersAuthorizeAttribute.cs b/src/Umbraco.Web/WebApi/Filters/AdminUsersAuthorizeAttribute.cs
index 96226622b0..3494a5c0c7 100644
--- a/src/Umbraco.Web/WebApi/Filters/AdminUsersAuthorizeAttribute.cs
+++ b/src/Umbraco.Web/WebApi/Filters/AdminUsersAuthorizeAttribute.cs
@@ -50,7 +50,7 @@ namespace Umbraco.Web.WebApi.Filters
if (userIds.Length == 0) return base.IsAuthorized(actionContext);
var users = Current.Services.UserService.GetUsersById(userIds);
- var authHelper = new UserEditorAuthorizationHelper(Current.Services.ContentService, Current.Services.MediaService, Current.Services.UserService, Current.Services.EntityService);
+ var authHelper = new UserEditorAuthorizationHelper(Current.Services.ContentService, Current.Services.MediaService, Current.Services.UserService, Current.Services.EntityService, Current.AppCaches);
return users.All(user => authHelper.IsAuthorized(Current.UmbracoContext.Security.CurrentUser, user, null, null, null) != false);
}
}
diff --git a/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs b/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs
index 2a57ec10b2..3bbee7ca41 100644
--- a/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs
+++ b/src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs
@@ -85,12 +85,12 @@ namespace Umbraco.Web.WebApi.Filters
() => user.Groups.Select(x => x.Alias).UnsortedSequenceEqual(identity.Roles) == false,
() =>
{
- var startContentIds = UserExtensions.CalculateContentStartNodeIds(user, Current.Services.EntityService);
+ var startContentIds = UserExtensions.CalculateContentStartNodeIds(user, Current.Services.EntityService, Current.AppCaches);
return startContentIds.UnsortedSequenceEqual(identity.StartContentNodes) == false;
},
() =>
{
- var startMediaIds = UserExtensions.CalculateMediaStartNodeIds(user, Current.Services.EntityService);
+ var startMediaIds = UserExtensions.CalculateMediaStartNodeIds(user, Current.Services.EntityService, Current.AppCaches);
return startMediaIds.UnsortedSequenceEqual(identity.StartMediaNodes) == false;
}
};
diff --git a/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs b/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs
index 550b4dcdf1..0f08d353a6 100644
--- a/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs
+++ b/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs
@@ -115,11 +115,13 @@ namespace Umbraco.Web.WebApi.Filters
nodeId = _nodeId.Value;
}
- var permissionResult = ContentPermissionsHelper.CheckPermissions(nodeId,
+ var permissionResult = ContentPermissionsHelper.CheckPermissions(
+ nodeId,
Current.UmbracoContext.Security.CurrentUser,
Current.Services.UserService,
Current.Services.ContentService,
Current.Services.EntityService,
+ Current.AppCaches,
out var contentItem,
_permissionToCheck.HasValue ? new[] { _permissionToCheck.Value } : null);
diff --git a/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForMediaAttribute.cs b/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForMediaAttribute.cs
index 3c60f43be0..4506fcf14d 100644
--- a/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForMediaAttribute.cs
+++ b/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForMediaAttribute.cs
@@ -124,6 +124,7 @@ namespace Umbraco.Web.WebApi.Filters
Current.UmbracoContext.Security.CurrentUser,
Current.Services.MediaService,
Current.Services.EntityService,
+ Current.AppCaches,
nodeId))
{
base.OnActionExecuting(actionContext);
diff --git a/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs b/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs
index 31e0b22ce1..24fd60cd26 100644
--- a/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs
+++ b/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs
@@ -9,7 +9,7 @@ using Umbraco.Core;
using Umbraco.Web.Composing;
using Umbraco.Core.Models;
using Umbraco.Web.Actions;
-
+using Umbraco.Core.Cache;
namespace Umbraco.Web.WebApi.Filters
{
@@ -21,52 +21,58 @@ namespace Umbraco.Web.WebApi.Filters
{
private readonly IUserService _userService;
private readonly IEntityService _entityService;
+ private readonly AppCaches _appCaches;
private readonly char _permissionToCheck;
public FilterAllowedOutgoingContentAttribute(Type outgoingType)
- : this(outgoingType, Current.Services.UserService, Current.Services.EntityService)
+ : this(outgoingType, ActionBrowse.ActionLetter, string.Empty, Current.Services.UserService, Current.Services.EntityService, Current.AppCaches)
{
- _permissionToCheck = ActionBrowse.ActionLetter;
}
public FilterAllowedOutgoingContentAttribute(Type outgoingType, char permissionToCheck)
- : this(outgoingType, Current.Services.UserService, Current.Services.EntityService)
+ : this(outgoingType, permissionToCheck, string.Empty, Current.Services.UserService, Current.Services.EntityService, Current.AppCaches)
{
- _permissionToCheck = permissionToCheck;
}
public FilterAllowedOutgoingContentAttribute(Type outgoingType, string propertyName)
- : this(outgoingType, propertyName, Current.Services.UserService, Current.Services.EntityService)
+ : this(outgoingType, ActionBrowse.ActionLetter, propertyName, Current.Services.UserService, Current.Services.EntityService, Current.AppCaches)
{
- _permissionToCheck = ActionBrowse.ActionLetter;
}
public FilterAllowedOutgoingContentAttribute(Type outgoingType, IUserService userService, IEntityService entityService)
- : base(outgoingType)
+ : this(outgoingType, ActionBrowse.ActionLetter, string.Empty, userService, entityService, Current.AppCaches)
+ {
+ }
+
+ public FilterAllowedOutgoingContentAttribute(Type outgoingType, IUserService userService, IEntityService entityService, AppCaches appCaches)
+ : this(outgoingType, ActionBrowse.ActionLetter, string.Empty, userService, entityService, appCaches)
{
- _userService = userService ?? throw new ArgumentNullException(nameof(userService));
- _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService));
- _permissionToCheck = ActionBrowse.ActionLetter;
}
public FilterAllowedOutgoingContentAttribute(Type outgoingType, char permissionToCheck, IUserService userService, IEntityService entityService)
- : base(outgoingType)
+ : this(outgoingType, permissionToCheck, string.Empty, userService, entityService, Current.AppCaches)
{
- _userService = userService ?? throw new ArgumentNullException(nameof(userService));
- _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService));
- _userService = userService;
- _entityService = entityService;
- _permissionToCheck = permissionToCheck;
}
public FilterAllowedOutgoingContentAttribute(Type outgoingType, string propertyName, IUserService userService, IEntityService entityService)
+ : this(outgoingType, ActionBrowse.ActionLetter, propertyName, userService, entityService, Current.AppCaches)
+ {
+ }
+
+ public FilterAllowedOutgoingContentAttribute(Type outgoingType, string propertyName, IUserService userService, IEntityService entityService, AppCaches appCaches)
+ : this(outgoingType, ActionBrowse.ActionLetter, propertyName, userService, entityService, appCaches)
+ {
+ }
+
+ private FilterAllowedOutgoingContentAttribute(Type outgoingType, char permissionToCheck, string propertyName, IUserService userService, IEntityService entityService, AppCaches appCaches)
: base(outgoingType, propertyName)
{
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
_entityService = entityService ?? throw new ArgumentNullException(nameof(entityService));
+ _appCaches = appCaches;
_userService = userService;
_entityService = entityService;
- _permissionToCheck = ActionBrowse.ActionLetter;
+ _permissionToCheck = permissionToCheck;
}
protected override void FilterItems(IUser user, IList items)
@@ -78,7 +84,7 @@ namespace Umbraco.Web.WebApi.Filters
protected override int[] GetUserStartNodes(IUser user)
{
- return user.CalculateContentStartNodeIds(_entityService);
+ return user.CalculateContentStartNodeIds(_entityService, _appCaches);
}
protected override int RecycleBinId
@@ -110,7 +116,7 @@ namespace Umbraco.Web.WebApi.Filters
if (nodePermission.Contains(_permissionToCheck.ToString(CultureInfo.InvariantCulture)) == false)
{
toRemove.Add(item);
- }
+ }
}
foreach (var item in toRemove)
{
diff --git a/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingMediaAttribute.cs b/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingMediaAttribute.cs
index 21dc60e6cc..5e308bd3c1 100644
--- a/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingMediaAttribute.cs
+++ b/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingMediaAttribute.cs
@@ -39,7 +39,7 @@ namespace Umbraco.Web.WebApi.Filters
protected virtual int[] GetUserStartNodes(IUser user)
{
- return user.CalculateMediaStartNodeIds(Current.Services.EntityService);
+ return user.CalculateMediaStartNodeIds(Current.Services.EntityService, Current.AppCaches);
}
protected virtual int RecycleBinId => Constants.System.RecycleBinMedia;