Updates logic to ensure that if we are rendering site nodes that we don't render all of their children, we will filter out any nodes that do not belong to the user's start nodes' branches

This commit is contained in:
Shannon
2017-09-06 00:38:31 +10:00
parent 186fd1166a
commit c860069215
2 changed files with 103 additions and 14 deletions

View File

@@ -162,8 +162,8 @@ namespace Umbraco.Core.Models
default:
throw new NotSupportedException("Path access is only determined on content or media");
}
}
}
internal static bool HasPathAccess(string path, int[] startNodeIds, int recycleBinId)
{
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Value cannot be null or whitespace.", "path");
@@ -176,16 +176,73 @@ namespace Umbraco.Core.Models
if (startNodeIds.Contains(Constants.System.Root))
return true;
var formattedPath = "," + path + ",";
var formattedPath = string.Concat(",", path, ",");
// only users with root access have access to the recycle bin,
// if the above check didn't pass then access is denied
if (formattedPath.Contains("," + recycleBinId + ","))
if (formattedPath.Contains(string.Concat(",", recycleBinId, ",")))
return false;
// check for a start node in the path
return startNodeIds.Any(x => formattedPath.Contains("," + x + ","));
return startNodeIds.Any(x => formattedPath.Contains(string.Concat(",", x, ",")));
}
internal static bool IsInBranchOfStartNode(this IUser user, IUmbracoEntity entity, IEntityService entityService, int recycleBinId, out bool hasPathAccess)
{
switch (recycleBinId)
{
case Constants.System.RecycleBinMedia:
return IsInBranchOfStartNode(entity.Path, user.CalculateMediaStartNodeIds(entityService), user.GetMediaStartNodePaths(entityService), out hasPathAccess);
case Constants.System.RecycleBinContent:
return IsInBranchOfStartNode(entity.Path, user.CalculateContentStartNodeIds(entityService), user.GetContentStartNodePaths(entityService), out hasPathAccess);
default:
throw new NotSupportedException("Path access is only determined on content or media");
}
}
internal static bool IsInBranchOfStartNode(string path, int[] startNodeIds, string[] startNodePaths, out bool hasPathAccess)
{
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Value cannot be null or whitespace.", "path");
hasPathAccess = false;
// check for no access
if (startNodeIds.Length == 0)
return false;
// check for root access
if (startNodeIds.Contains(Constants.System.Root))
{
hasPathAccess = true;
return true;
}
//is it self?
var self = startNodePaths.Any(x => x == path);
if (self)
{
hasPathAccess = true;
return true;
}
//is it ancestor?
var ancestor = startNodePaths.Any(x => x.StartsWith(path));
if (ancestor)
{
hasPathAccess = false;
return true;
}
//is it descendant?
var descendant = startNodePaths.Any(x => path.StartsWith(x));
if (descendant)
{
hasPathAccess = true;
return true;
}
return false;
}
/// <summary>
/// Determines whether this user is an admin.
@@ -205,7 +262,7 @@ namespace Umbraco.Core.Models
{
const string cacheKey = "AllContentStartNodes";
//try to look them up from cache so we don't recalculate
var valuesInUserCache = FromUserCache(user, cacheKey);
var valuesInUserCache = FromUserCache<int[]>(user, cacheKey);
if (valuesInUserCache != null) return valuesInUserCache;
var gsn = user.Groups.Where(x => x.StartContentId.HasValue).Select(x => x.StartContentId.Value).Distinct().ToArray();
@@ -220,7 +277,7 @@ namespace Umbraco.Core.Models
{
const string cacheKey = "AllMediaStartNodes";
//try to look them up from cache so we don't recalculate
var valuesInUserCache = FromUserCache(user, cacheKey);
var valuesInUserCache = FromUserCache<int[]>(user, cacheKey);
if (valuesInUserCache != null) return valuesInUserCache;
var gsn = user.Groups.Where(x => x.StartMediaId.HasValue).Select(x => x.StartMediaId.Value).Distinct().ToArray();
@@ -228,9 +285,36 @@ namespace Umbraco.Core.Models
var vals = CombineStartNodes(UmbracoObjectTypes.Media, gsn, usn, entityService);
ToUserCache(user, cacheKey, vals);
return vals;
}
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<string[]>(user, cacheKey);
if (valuesInUserCache != null) return valuesInUserCache;
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[] GetContentStartNodePaths(this IUser user, IEntityService entityService)
{
const string cacheKey = "ContentStartNodePaths";
//try to look them up from cache so we don't recalculate
var valuesInUserCache = FromUserCache<string[]>(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 int[] FromUserCache(IUser user, string cacheKey)
private static T FromUserCache<T>(IUser user, string cacheKey)
where T: class
{
var entityUser = user as User;
if (entityUser == null) return null;
@@ -239,12 +323,13 @@ namespace Umbraco.Core.Models
{
object allContentStartNodes;
return entityUser.AdditionalData.TryGetValue(cacheKey, out allContentStartNodes)
? allContentStartNodes as int[]
? allContentStartNodes as T
: null;
}
}
private static void ToUserCache(IUser user, string cacheKey, int[] vals)
private static void ToUserCache<T>(IUser user, string cacheKey, T vals)
where T: class
{
var entityUser = user as User;
if (entityUser == null) return;